Reputation: 686
I have a list of objects that holds contract information List<Contract> endedContracts
that has already been filtered out from a larger list. I am now trying to match the info in this list to records in my database with some further filters.
var endedContracts = _contracts
.Where(x => x.Contract.IsContractInLastBillingPeriod(referencePeriod))
.Where(x => x.Contract.IsContractCoveredByLiveInvoices(x.Contract.Invoices)).ToList();
When I run the below query I get the error.
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();
The exact error:
Unable to create a constant value of type 'Contract'. Only primitive types or enumeration types are supported in this context."
Upvotes: 1
Views: 5365
Reputation: 4765
Notice that endedContracts
is a collection in memory and the linq is to be transalted to sql which will be executed within the database service
Entity Framework cannot upload the whole data collection to the database, so when the query is executing, there are no endedContracts
.
Thus you have 2 options to make it work:
Let the endedContracts
be a query object (IQueryable) rather than executing it (ToList()
) then the whole query would be translated and executed in the database service.
Executing the query to retrive both data sets and execute in-memory linq (that may be a serious performance problem).
Conclusion, the iteration of both datasets must take place in the same machine, the .NET application or the database.
Upvotes: 1
Reputation: 118937
endedContracts
is an in memory list and cannot be used directly in this query. Instead, get the value you need outside of the query, for example:
//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();
Upvotes: 1