27

我想运行这个 LINQ 简单代码以在 LINQ 中有记录号,但结果低于错误

var model = _db2.Persons.Select(
    (x, index) => new 
    {
        rn = index + 1,
        col1 = x.Id
    }).ToList();

错误:

LINQ to Entities 无法识别方法 'System.Linq.IQueryable 1[<>f__AnonymousType22 [System.Int32,System.Int32]] Select[Person,<>f__AnonymousType2 2](System.Linq.IQueryable1 [MvcApplication27.Models.Person], System.Linq.Expressions.Expression 1[System.Func3 [ MvcApplication27.Models.Person,System.Int32,<>f__AnonymousType2`2 [System.Int32,System.Int32]]])' 方法,并且该方法不能翻译成存储表达式。

4

2 回答 2

27

问题是 LINQ to Entities 不了解如何将该Select重载(为您提供索引的重载)转换为 SQL 查询。您可以通过首先从您需要的数据库中选择部分来解决此问题(以避免不必要地选择每一列),然后AsEnumerable()将其作为 anIEnumerable<T>而不是 an IQueryable<T>,然后Select纯粹在 C# 中执行(简而言之,IQueryable<T>将 s 转换为 SQL , 而IEnumerable<T>s 在代码中运行)。

var model = _db2.Persons.Select(x => x.Id).AsEnumerable().Select(
    (id, index) => new
    {
        rn = index + 1,
        col1 = id
    }).ToList();

请注意,您拥有的查询似乎是无序的,因此每次调用它时 id/index 配对都会发生变化。如果您期望一致性,您应该按一些东西(例如_db2.Persons.OrderBy(...))排序。

编辑

添加来自Scott的评论:

作为一个很好的参考,这里列出了框架中内置的所有 Linq 语句,以及它是否兼容的列表

于 2013-09-13T14:34:47.237 回答
2

您可以只选择 Id,然后使用 linq to objects 创建您自己的匿名对象,例如:

var model = _db2.Persons.Select(x => x.Id)
                        .ToList() // return int[]
                        .Select((id, index) => new
                                {
                                    rn = index + 1,
                                    col1 = id
                                 }) // return anonymous[] (with rn and col1)
                         .AsEnumerable(); // get an IEnumerable (readonly collection)

可能会发生这种情况,因为实体框架不支持使用 linq 的这种查询,因为 linq 可以在内存中执行,因此,在这种情况下,您可以选择您需要的(id在您的情况下)并执行它,使用ToList()方法来具体化您的查询之后,您将拥有一个内存列表,因此,您可以使用 linq to objects 并根据需要使用支持的方法。

于 2013-09-13T14:30:46.440 回答