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 для объектов и использовать поддерживаемый метод по своему усмотрению.