使用SQL Server时模拟实体框架的.Last()

时间:2018-03-16 15:37:42

标签: c# sql-server entity-framework entity-framework-6

SQL Server能够使用其函数.First()翻译EF TOP(1)。但是当使用Entity Framework的.Last()函数时,它会引发异常。由于显而易见的原因,SQL服务器无法识别此类函数。

我曾经通过排序降序并取第一条相应的行来处理它:

var v = db.Table.OrderByDescending(t => t.ID).FirstOrDefault(t => t.ClientNumber == ClientNumberDetected);

这是通过单个查询完成的,但在查询之前对整个表(百万行)进行排序......

如果我滥用这种技术,我是否有充分的理由认为会出现速度问题?

我想到了类似的东西......但它需要两个查询:

int maxID_of_Client = db.Where(t => t.ClientNumber == ClientNumberDetected).Max(t => t.ID);

var v = db.First(t => t.ID == maxID_of_Client);

它包括检索客户端的最大ID,然后使用此ID检索客户端的最后一行。

两次查询似乎更快......

必须有一种优化方法并使用单个查询而无需对数百万个数据进行排序。

除非有一些我不明白的事情,否则我可能不是第一个想到这个问题的人,我想要好好解决它!

提前致谢。

1 个答案:

答案 0 :(得分:2)

推动这个问题的假设是没有排序条款的结果集以任何可预测的顺序从你的数据库中返回。

实际上,从SQL返回的结果集没有隐式排序,也不应该假设。

因此,

的结果
db.Table.FirstOrDefault(t => t.ClientNumber == ClientNumberDetected)

实际上是不确定的。

无论你是第一次还是最后一次,没有订购,无论如何都没有意义。

现在,在LINQ中添加一个排序子句的SQL是什么?它将类似于......

SELECT TOP(1) something FROM somewhere WHERE foo=bar ORDER BY somevalue

或者,在降序/最后一种情况下

SELECT TOP(1) something FROM somewhere WHERE foo=bar ORDER BY somevalue DESC

从SQL的POV,这里没有显着差异,您的数据库将针对此类查询进行优化。可以在任一方向扫描索引,并且上面每个查询的成本相同。

TL; DR

db.Table.OrderByDescending(t => t.ID)
        .FirstOrDefault(t => t.ClientNumber == ClientNumberDetected)

很好。