LINQ对实体不认识方法Last。真? [英] LINQ To Entities does not recognize the method Last. Really?

查看:127
本文介绍了LINQ对实体不认识方法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

编辑:

另一个效率较低的替代方案 - 我不推荐这个! - 是在$ code> .Last()之前调用 .ToList(),这将立即执行LINQ To Entities Expression已经建立到这一点,然后你的.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对实体不认识方法Last。真?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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