gpt4 book ai didi

c# - Linq Except 未按预期运行 - 重复项目

转载 作者:行者123 更新时间:2023-11-30 17:48:09 25 4
gpt4 key购买 nike

新问题

在绕过房子之后,我认为 Except 不是问题所在。我认为从数据库中选择是错误的。因此我提出了一个新问题Where returns wrong record .这个问题将被关闭 - 或者我会修改另一个问题的答案。

我正在尝试将 Linq Except() 方法与自定义比较器结合使用。我认为一切正常,因为我的数据集从 2k 条记录大幅缩减到 62 条。但是在剩下的 62 条记录中,我有一个重复项(数据库中已经存在的项目),我不确定如何。

这是我在监 window 口中的重复条目:

enter image description here

和数据库中的条目类似(PostcodeKey和Zone_ID是复合主键)

enter image description here

我只是应该在保存之前从我的收藏中删除数据库中已经存在的任何项目(这是通过 CSV 导入):

IEnumerable<ZoneMapping> items // parameter passed in

// Exclude any items that we already have
items = items.Except(this.context.ZoneMappings.Include("Zone"), new ZoneMappingComparer()).ToList();

// Process all the items and save them
foreach (ZoneMapping item in items)
{
this.context.ZoneMappings.Add(item);
}

this.context.SaveChanges();

我已经验证了我的上下文中的数据库计数和 ZoneMappings.Count() 是相同的。我的比较器非常简单:

public class ZoneMappingComparer : IEqualityComparer<ZoneMapping>
{
/// <inheritdoc/>
public bool Equals(ZoneMapping x, ZoneMapping y)
{
if (x == null && y == null)
return true;

if (x == null || y == null)
return false;

if (x.PostcodeKey == "2214" && y.PostcodeKey == "2214")
Debugger.Break();

// Compare the Postcode Key
int compareResult = x.PostcodeKey.CompareTo(y.PostcodeKey);
if (compareResult != 0)
return false;

// Compare the Zone
if (x.Zone == null && y.Zone == null)
return true;

// Compare the Zone
if (x.Zone == null || y.Zone == null)
return false;

compareResult = x.Zone.ID.CompareTo(y.Zone.ID);
return compareResult == 0;
}

/// <inheritdoc/>
public int GetHashCode(ZoneMapping obj)
{
return obj.PostcodeKey.GetHashCode() + ((obj.Zone != null) ? obj.Zone.ID.GetHashCode() : 0);
}
}

如您所见,我在其中放置了一个 Debugger.Break(),它会触发并且在方法结束时 compareResult 为 0。

如果我继续执行直到保存,但是我会收到带有以下消息的 UpdateException:

{"Violation of PRIMARY KEY constraint 'PK_dbo.NetC_EF_ZoneMapping'. Cannot insert duplicate key in object 'dbo.NetC_EF_ZoneMapping'. The duplicate key value is (2214, 257).\r\nThe statement has been terminated."}

我是否误解了 Except 应该如何工作?还是我遗漏了其他明显的东西?

编辑

我已经尝试过 Chris 的建议,可能是转移注意力但我已经切换到手动填充我的列表:

// Exclude any items that we already have
items = new List<ZoneMapping>() { new ZoneMapping() { PostcodeKey = "2214", Zone = new Zone() { ID = 257 } } };
items = items.Except(this.context.ZoneMappings.Include("Zone"), new ZoneMappingComparer()).ToList();

ZoneMapping mapping = this.context.ZoneMappings.Include("Zone").Where(z => z.PostcodeKey == "2214" && z.Zone.ID == 257).First();
var comparer = new ZoneMappingComparer();
if (comparer.Equals(items.ToList()[0], mapping))
{
Debugger.Break();
}

奇怪的是,此时我从上下文中得到的 Zone 是错误的:

enter image description here

另一张图片说明返回的错误记录和生成的 SQL(看起来不错)。如果我对相同的影响运行自动化测试,它会正常工作并返回正确的记录。

enter image description here

这是我的 ZoneMapping 类:

 /// <summary>
/// Represents a mapping between a postcode and a zone
/// </summary>
[Table("NetC_EF_ZoneMapping")]
public class ZoneMapping
{
/// <summary>
/// Gets or sets the postcode identifier
/// </summary>
[Key]
public String PostcodeKey { get; set; }

/// <summary>
/// Gets or sets the Zone identifier
/// </summary>
[Key]
public Zone Zone { get; set; }
}

最佳答案

在这种情况下,实际上使用 Where 子句更清楚地说明了问题。实际问题是由于 PrimaryKey 应用于实体,而不是简单的字段。参见 Where returns wrong record了解更多详情

关于c# - Linq Except 未按预期运行 - 重复项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23537503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com