Ошибка LINQ Query: невозможно создать постоянное значение типа. В этом контексте поддерживаются только примитивные типы или типы перечисления - PullRequest
1 голос
/ 16 мая 2019

У меня есть список объектов, который содержит информацию о контракте List<Contract> endedContracts, которая уже была отфильтрована из большого списка. Сейчас я пытаюсь сопоставить информацию в этом списке с записями в моей базе данных с некоторыми дополнительными фильтрами.

var endedContracts = _contracts
    .Where(x => x.Contract.IsContractInLastBillingPeriod(referencePeriod))
    .Where(x => x.Contract.IsContractCoveredByLiveInvoices(x.Contract.Invoices)).ToList();

Когда я запускаю приведенный ниже запрос, я получаю сообщение об ошибке.

var crystallisedCommissions = _context.Contracts
   .Where(x => x.Statement.Sent)
   .Where(x => x.Statement.Broker == endedContracts.First().Broker.Code)
   .Where(x => !Period.IsPeriodBeforeReferencePeriod(x.Statement.Period, CUT_OFF_PERIOD))
   .Where(x => endedContracts.Any(y => y.Contract.Identifier == x.Identifier
                                    && y.Contract.StartDate == x.ContractStartDate
                                    && y.Contract.EndDate == x.ContractEndDate)).ToList();

Точная ошибка:

Невозможно создать постоянное значение типа 'Контракт'. В этом контексте поддерживаются только примитивные типы или типы перечисления. "

Ответы [ 2 ]

1 голос
/ 16 мая 2019

Обратите внимание, что endedContracts - это коллекция в памяти, и linq должен быть преобразован в sql, который будет выполняться в службе базы данных. Entity Framework не может загрузить весь сбор данных в базу данных, поэтому при выполнении запроса существуетendedContracts.

Таким образом, у вас есть 2 варианта, чтобы заставить его работать:

  1. Позвольте endedContracts быть объектом запроса (IQueryable), а не выполнять его(ToList()) тогда весь запрос будет переведен и выполнен в службе базы данных.

  2. Выполнение запроса для извлечения обоих наборов данных и выполнения linq в памяти (который может бытьсерьезная проблема с производительностью).

Вывод: итерация обоих наборов данных должна выполняться на одном компьютере, в приложении .NET или в базе данных.

1 голос
/ 16 мая 2019

endedContracts находится в списке памяти и не может использоваться непосредственно в этом запросе. Вместо этого получите нужное значение вне запроса, например:

//Get the code here
var brokerCode = endedContracts.First().Broker.Code;

var crystallisedCommissions = _context.Contracts
   .Where(x => x.Statement.Sent)
   .Where(x => x.Statement.Broker == brokerCode) //Use the code here
   .Where(x => !Period.IsPeriodBeforeReferencePeriod(x.Statement.Period, CUT_OFF_PERIOD))
   .Where(x => endedContracts.Any(y => y.Contract.Identifier == x.Identifier
                                    && y.Contract.StartDate == x.ContractStartDate
                                    && y.Contract.EndDate == x.ContractEndDate)).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...