LINQ To Entities 无法识别 Last 方法.真的吗? [英] LINQ To Entities does not recognize the method Last. Really?

查看:30
本文介绍了LINQ To Entities 无法识别 Last 方法.真的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个查询中:

public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
    var context = DataContext.GetDataContext();
    return context.ServerOnlineCharacters
        .OrderBy(p => p.ServerStatus.ServerDateTime)
        .GroupBy(p => p.RawName)
        .Select(p => p.Last());
}

我必须把它切换到这个才能工作

I had to switch it to this for it to work

public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
    var context = DataContext.GetDataContext();
    return context.ServerOnlineCharacters
        .OrderByDescending(p => p.ServerStatus.ServerDateTime)
        .GroupBy(p => p.RawName)
        .Select(p => p.FirstOrDefault());
}

我什至不能使用 p.First() 来镜像第一个查询.

I couldn't even use p.First(), to mirror the first query.

为什么如此强大的 ORM 系统会有如此基本的限制?

Why are there such basic limitations in what's otherwise such a robust ORM system?

推荐答案

这个限制归结为这样一个事实,即最终它必须将该查询转换为 SQL 并且 SQL 有一个 SELECT TOP(在 T-SQL 中)但不是 SELECT BOTTOM(没有这样的东西).

That limitation comes down to the fact that eventually it has to translate that query to SQL and SQL has a SELECT TOP (in T-SQL) but not a SELECT BOTTOM (no such thing).

不过有一个简单的方法,只需降序,然后执行First(),这就是您所做的.

There is an easy way around it though, just order descending and then do a First(), which is what you did.

其他提供者可能有不同的 SELECT TOP 1 实现,在 Oracle 上它可能更像是 WHERE ROWNUM = 1

Other providers will possibly have different implementations of SELECT TOP 1, on Oracle it would probably be something more like WHERE ROWNUM = 1

另一个效率较低的替代方案 - 我不推荐这样做! - 是在 .Last().ToList()>,它将立即执行到该点为止构建的 LINQ To Entities 表达式,然后您的 .Last() 将起作用,因为此时 .Last()LINQ to Objects 表达式的上下文.(正如您所指出的,它可能会带回数千条记录并浪费大量永远不会被使用的 CPU 物化对象)

Another less efficient alternative - I DO NOT recommend this! - is to call .ToList() on your data before .Last(), which will immediately execute the LINQ To Entities Expression that has been built up to that point, and then your .Last() will work, because at that point the .Last() is effectively executed in the context of a LINQ to Objects Expression instead. (And as you pointed out, it could bring back thousands of records and waste loads of CPU materialising objects that will never get used)

同样,我不建议这样做,但它确实有助于说明执行 LINQ 表达式的位置和时间之间的区别.

Again, I would not recommend doing this second, but it does help illustrate the difference between where and when the LINQ expression is executed.

这篇关于LINQ To Entities 无法识别 Last 方法.真的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆