LINQ To Entities无法识别方法Last。真?

时间:2011-09-03 14:14:45

标签: c# entity-framework orm

在此查询中:

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

我不得不将其切换到此工作

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()镜像第一个查询。

为什么在这种强大的ORM系统中存在这样的基本限制?

6 个答案:

答案 0 :(得分:203)

这种限制归结为最终它必须将该查询转换为 SQL 而SQL具有SELECT TOP(在T-SQL中)而不是SELECT BOTTOM (没有这样的事情)。

虽然有一种简单的方法,只需降序,然后执行First(),这就是你所做的。

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

修改

另一种效率较低的替代方案 - 我不建议这样做! - 是在.ToList()之前调用数据.Last(),这将立即执行LINQ To Entities Expression已构建到那一点,然后你的.Last()将起作用,因为此时.Last()有效地在 LINQ to Objects 表达式的上下文中执行。 (正如你所指出的那样,它可以带回数以千计的记录并浪费大量的CPU实现永远不会被使用的对象)

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

答案 1 :(得分:30)

取代Last(),试试这个:

model.OrderByDescending(o => o.Id).FirstOrDefault();

答案 2 :(得分:14)

将Linq选择器Last()

替换为OrderByDescending(x => x.ID).Take(1).Single()

如果您在Linq中执行此操作,那将是有效的:

public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
    var context = DataContext.GetDataContext();
    return context.ServerOnlineCharacters.OrderBy(p => p.ServerStatus.ServerDateTime).GroupBy(p => p.RawName).Select(p => p.OrderByDescending(x => x.Id).Take(1).Single());
}

答案 3 :(得分:0)

另一种方法是获取没有OrderByDescending的最后一个元素并加载所有实体:

dbSet
    .Where(f => f.Id == dbSet.Max(f2 => f2.Id))
    .FirstOrDefault();

答案 4 :(得分:0)

这是因为LINQ to Entities(和一般的数据库)不支持所有LINQ方法(有关详细信息,请参见此处:http://msdn.microsoft.com/en-us/library/bb738550.aspx

这里您需要的是对数据进行排序,以使“最后”记录变为“第一”,然后可以使用FirstOrDefault。请注意,databasese通常没有诸如“ first”和“ last”之类的概念,这与表中最近插入的记录不是“ last”一样。

这种方法可以解决您的问题

db.databaseTable.OrderByDescending(obj => obj.Id).FirstOrDefault();

答案 5 :(得分:-2)

在Select函数对我有用之前,添加一个函数AsEnumerable()
 示例:

return context.ServerOnlineCharacters
    .OrderByDescending(p => p.ServerStatus.ServerDateTime)
    .GroupBy(p => p.RawName).AsEnumerable()
    .Select(p => p.FirstOrDefault());

参考: https://www.codeproject.com/Questions/1005274/LINQ-to-Entities-does-not-recognize-the-method-Sys