我的问题更为笼统,但我有一个例子来帮助说明:
db.aTable.Where(x => x.Date < someDateInThePast).OrderByDescending(x => x.Date).First()
这给了我一个项目,它与此命令返回的项目不同:
db.aTable.Where(x => x.Date < someDateInThePast).ToList().OrderByDescending(x => x.Date).First()
(注意中间的“ToList()”。
从我所看到的,第一个例子中实际发生的事情是OrderBy完全忽略了.Where()所做的过滤。它命令整个aTable
。
第二个查询给出了实际正确的项目。
.Date
参数是DateTime类型(在SQL端,它是'datetime')。
从LINQ到实体是否需要这种行为?
答案 0 :(得分:0)
通过添加.ToList()
,您实际上会更改处理数据的上下文。
您的第一个查询完全由您的数据库处理,您只需将.First()
的值返回到您的实体实例。
在第二个中,你基本上给命令加载条件aTable
,给他命令.ToList()
,然后命令它,添加第二个条件并选择第一个{{1}来自那个已经实例化的表的值。
Microsoft声明link CLR更改可能会导致意外结果,这就是您正在做的事情。
确切地知道发生了什么的一种方法是直接在SQL Server上执行语句:
Date
然后为您的数据创建一个dbset,直到上下文发生变化:
Select Top(1) Date
From aTable
Where Date < someDateInThePast
order by Date desc
然后在c#环境中单独调用它。然后检查结果是否仍然不同。
希望这有帮助!
答案 1 :(得分:0)
我无法完全解释为什么它会像这样工作,但我发现包含First()
是造成问题的原因。当我查看LINQ生成的原始SQL时,没有引用&#39; Order By&#39;在里面。我只能假设订单发生在客户端。但是,有参考采取TOP(1)&#39;在SQL中。这意味着,因为SQL服务器只返回1个结果,所以order by仅在1个结果上发生,并且没有做任何有用的事情。
如果我将First()
更改为ToList()
,则排序按预期工作。这并不能解决我的问题,但它解释了这种行为。