Member 12285600 Ответов: 1

В этом контексте поддерживаются только примитивные типы или типы перечислений


Я думаю, что понимаю, почему мой код не работает, а именно потому, что я пытаюсь сравнить список в памяти с моей базой данных. Однако я не могу придумать, как обойти эту проблему?

У меня есть список, который содержит номера заказов, и мне нужно выбрать записи из базы данных, где номера заказов совпадают, и обновить запись до экспортированной.

Что я уже пробовал:

var ordernumbers = list.GroupBy(x => x.OrderReferenceNumber).ToList();

          var update = (from c in _context.CDMains
                        where ordernumbers.Any(x => x.Key == c.OrderReferenceNumber)
                        select c).ToList();


          foreach (var item in update)
          {
              item.Exported = true;
              _context.Entry(item).State = EntityState.Modified;
          }

F-ES Sitecore

EF преобразует синтаксис вашего запроса в инструкцию SQL, однако "ordernumbers" - это список объектов, существующих в памяти вашего приложения, так как же вы можете написать инструкцию SQL, которая проверяет память вызывающего приложения?

Вероятно, вам придется переупорядочить свой оператор так, чтобы вы действовали на c.OrderReferenceNumber и проверяли, находится ли его значение в ordernumbers, так как оно может быть преобразовано в

Где OrderReferenceNumber IN (....)

Может быть что-то вроде этого

https://stackoverflow.com/questions/21641016/check-if-list-contains-item-from-other-list-in-entityframework

Member 12285600

Спасибо, это сработало, и теперь я лучше понимаю эту проблему.

1 Ответов

Рейтинг:
0

Maciej Los

Я знаю, что вы смогли решить свою проблему на основе Ф-Эс компания[^] комментарий. Но вы должны понимать, что такая ошибка вызвана Entity Framework, которая берет лямбда-выражение и пытается преобразовать его в SQL-запрос. Как ее обойти?

Попробуйте заменить это:

var ordernumbers = list.GroupBy(x => x.OrderReferenceNumber).ToList();

          var update = (from c in _context.CDMains
                        where ordernumbers.Any(x => x.Key == c.OrderReferenceNumber)
                        select c).ToList();

с:
var ordernumbers = list.GroupBy(x => x.OrderReferenceNumber).ToList();

var update = _context.CDMains.ToList()
    .Where(c=> ordernumbers.Any(x => x.Key == c.OrderReferenceNumber);


Магия делает первый шаг .ToList() метод, который загружает данные в память и позволяет использовать запрос LINQ.

[Обновление]
Ричард Диминг написал (в комментарии к этому решению):

Это загрузит всю таблицу в память, просто чтобы выбросить все записи, которые не совпадают.

Более эффективным решением было бы:

var ordernumbers = list.Select(x => x.OrderReferenceNumber).Distinct().ToList();
var update = (from c in _context.CDMains
              where ordernumbers.Contains(c.OrderReferenceNumber)
              select c).ToList();


Совет 8 – Как писать запросы в стиле " WHERE IN’ с помощью LINQ to Entities – Meta-Me[^]


Member 12285600

Спасибо Мацей Лос, это была полезная информация.

Maciej Los

Всегда пожалуйста.

Richard Deeming

Это загрузит всю таблицу в память, просто чтобы выбросить все записи, которые не совпадают.

Более эффективным решением было бы:

var ordernumbers = list.Select(x => x.OrderReferenceNumber).Distinct().ToList();
var update = (from c in _context.CDMains
              where ordernumbers.Contains(c.OrderReferenceNumber)
              select c).ToList();

Совет 8 – Как писать запросы в стиле " WHERE IN’ с помощью LINQ to Entities – Meta-Me[^]

Maciej Los

Спасибо, Ричард, за ценный комментарий. Ответ был обновлен.