我有一个对象列表,其中包含已经从较大列表中过滤掉的合同信息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();
确切的错误:
无法创建类型为“合同”的常量。在这种情况下,仅支持原始类型或枚举类型。“
答案 0 :(得分:1)
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();
答案 1 :(得分:1)
请注意,endedContracts
是内存中的集合,并且linq将被转换为将在数据库服务中执行的sql。
实体框架无法将整个数据集合上传到数据库,因此在执行查询时,没有endedContracts
。
因此,您有2种选择可以使其正常工作:
让endedContracts
成为查询对象(IQueryable)而不是执行它(ToList()
),然后整个查询将在数据库服务中转换和执行。
执行查询以检索两个数据集并执行内存中的linq(这可能是一个严重的性能问题)。
结论是,两个数据集的迭代必须在同一台计算机,.NET应用程序或数据库中进行。