LINQ to Entities не распознает метод "System.Linq.IQueryable"

Я хочу запустить этот простой код 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__AnonymousType2 2     [System.Int32, System.Int32]] Выберите [Лицо, < > f__AnonymousType2 2](System.Linq.IQueryable 1     [MvcApplication27.Models.Person], System.Linq.Expressions.Expression 1[System.Func 3     [MvcApplication27.Models.Person, System.Int32, < > f__AnonymousType2`2     [System.Int32, System.Int32]]]), и этот метод не может быть переведен в хранилище     выражение.

Ответы

Ответ 1

Проблема в том, что LINQ to Entities не понимает, как преобразовать эту перегрузку Select (ту, которая дает вам индекс) в SQL-запрос. Вы можете исправить это, сначала выбрав часть из необходимой вам БД (чтобы избежать ненужного выбора каждого столбца), затем сделав AsEnumerable(), чтобы принять его как IEnumerable<T> вместо IQueryable<T>, а затем выполнив Select чисто в С# (короче говоря, IQueryable<T> преобразуются в SQL, а IEnumerable<T> выполняются в коде).

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

Обратите внимание, что запрос, который у вас есть, кажется неупорядоченным, поэтому пары id/index могут меняться каждый раз, когда вы вызываете это. Если вы ожидали согласованности, вы должны заказать что-то (например, _db2.Persons.OrderBy(...)).

Ответ 2

Вы можете просто выбрать Id и после этого создать свой собственный анонимный объект, используя linq для объектов, для образца:

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)

Проще говоря, это происходит потому, что Entity Framework не поддерживает этот тип запросов с использованием linq, поскольку linq может делать в памяти, поэтому в этом случае вы можете выбрать только то, что вам нужно (id в вашем случае) и выполнить его, используя метод ToList() для конкретизации вашего запроса, и после этого у вас будет список в памяти, поэтому вы можете использовать linq для объектов и использовать поддерживаемый метод по своему усмотрению.