LINQ“Where"语句不成立

本文关键字:语句 quot Where LINQ | 更新日期: 2023-09-27 18:13:00

我有点困惑为什么这段代码在一个列表中产生2条记录(行为适当):

var historiesToRemove = new List<WorkHistory>();
                foreach (var history in this.WorkHistories)
                {
                    if (history.Tool.Equals(item))
                    {
                        historiesToRemove.Add(history);
                    }
                }

下面这段代码产生一个空列表:

var historiesToRemove = this.WorkHistories.Where(history => history.Tool.Equals(item)).ToList();

知道为什么会发生这种情况吗?

原因:

我没有正确实现IDbSet的IQueryable属性。

LINQ“Where"语句不成立

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

Edit:刚才看到您在查询的末尾有ToList,所以下面的内容不适用。


阅读闭包和LINQ。可能在您运行查询之前'item'正在更改。

示例问题代码:

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);

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

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