C# 林奇;其中;对账单不存在';行不通

C# 林奇;其中;对账单不存在';行不通,c#,.net,linq,entity-framework,linq-to-entities,C#,.net,Linq,Entity Framework,Linq To Entities,我有点困惑,为什么这段代码会在一个列表中生成两条记录(行为恰当): 你知道为什么会这样吗 原因: 我没有正确实现IDbSet的IQueryable属性。这使我的LINQ行为错误。编辑:刚刚看到您在查询末尾列出了列表,因此以下内容不适用 仔细阅读。在运行查询之前,“项”可能正在更改 问题代码示例: var filter = "Compare"; var query = from m in typeof(String).GetMethods() where m.Name.

我有点困惑,为什么这段代码会在一个列表中生成两条记录(行为恰当):

你知道为什么会这样吗

原因:


我没有正确实现IDbSet的IQueryable属性。这使我的LINQ行为错误。

编辑:刚刚看到您在查询末尾列出了
列表,因此以下内容不适用


仔细阅读。在运行查询之前,“项”可能正在更改

问题代码示例:

var filter = "Compare";

var query = from m in typeof(String).GetMethods()
            where m.Name.Contains(filter)
            select new { m.Name, ParameterCount = m.GetParameters().Length };

filter = "IndexOf";

foreach (var item in query)
    Console.WriteLine(item);

您在注释中提到的
IDbSet
是实体框架的一部分,因此您的两段代码并不等效。LINQ是一个表达式树,通过EF转换为SQL,而第一位代码从数据库中检索整个表并在内存中执行循环。对数据库进行概要分析,以了解数据库中正在执行的SQL,这应该会让您了解为什么linq不执行您想要的操作

这只是一个猜测,但我想说,您可能提供了一个与EF中LINQ翻译使用的定义不同的平等定义。在EF中,我相信它使用属性相等,而您可能只是检查ID是否相同。我建议您显式地编码要在LINQ语句中检查的平等定义。在第一种情况下,等式定义起作用的原因是枚举IDbSet会将其带到内存中,从而调用您的Equals版本,而不是Equals的LINQ到EF转换

 var historiesToRemove = this.WorkHistories.Where( h => h.Tool.ID == tool.ID )
                                           .ToList();

我不确定情况是否如此,因为
ToList()
调用lambda执行。刚刚编辑过。是否设置了工作历史记录?是。问题已解决,请阅读已接受答案的评论。您已接受的答案已被版主删除(可能是因为质量低)。在我看来,本·罗宾逊和特凡福森的回答都是正确的。(新)选项由您选择:)
var filter = "Compare";

var query = from m in typeof(String).GetMethods()
            where m.Name.Contains(filter)
            select new { m.Name, ParameterCount = m.GetParameters().Length };

filter = "IndexOf";

foreach (var item in query)
    Console.WriteLine(item);
 var historiesToRemove = this.WorkHistories.Where( h => h.Tool.ID == tool.ID )
                                           .ToList();