【发布时间】:2016-10-06 02:48:25
【问题描述】:
我有以下 linq 查询:
var fileDocuments = (
from doc in fileUploads
from invoice in
(
from inv in _dbContext.SupplierInvoiceHeaders
where inv.InvoiceDocumentId == doc.ID || inv.JobSheetInvoiceId == doc.ID
select inv
).DefaultIfEmpty()
join pos in _dbContext.PurchaseOrders on invoice.PurchaseOrder.PurchaseOrderId equals pos.PurchaseOrderId into poss
from po in poss.DefaultIfEmpty()
join hdf in _dbContext.HelpDeskFaults on po.HelpdeskFaultId equals hdf.ID into hdfpo
from hs in hdfpo.DefaultIfEmpty()
join store1 in _dbContext.Stores on hs.StoreID equals store1.ID into hsf
from hdfStore in hsf.DefaultIfEmpty()
join js in _dbContext.JobSheets on invoice.SupplierInvoiceHeaderId equals js.SupplierInvoiceHeaderID into jss
from jobSheets in jss.DefaultIfEmpty()
join ch in _dbContext.ChildProjects on po.ChildProjectId equals ch.ID into chs
from childProjects in chs.DefaultIfEmpty()
join ph in _dbContext.ProjectHeaders on childProjects.ProjectHeaderID equals ph.ID into phs
from projectHeaders in phs.DefaultIfEmpty()
join ppmsl in _dbContext.PpmScheduleLines on projectHeaders.PPMScheduleRef equals ppmsl.ID into ppsmsls
from ppmScheduleLines in ppsmsls.DefaultIfEmpty()
join ss2 in _dbContext.Stores on ppmScheduleLines.StoreID equals ss2.ID into ssts
from store2 in ssts.DefaultIfEmpty()
where getJobWhereClause(invoice, hs, ppmScheduleLines, doc)
select new
{
doc.ID,
JobSheetId = jobSheets.DocumentID,
doc.Name,
doc.DateCreated,
doc.StoreID,
StoreName = doc.Store.Name,
DocumentType = doc.DocumentType.Name,
doc.DocumentTypeID
})
.AsEnumerable()
.Distinct()
.Select(d => new JobDocumentDto
{
ID = d.ID,
DocumentID = (d.JobSheetId) ?? d.ID,
DocumentName = d.Name,
DateCreated = d.DateCreated.ToString("dd/MM/yyyy"),
StoreName = d.StoreName,
DocumentTypeName = d.DocumentType,
DocumentTypeId = d.DocumentTypeID
}).OrderByDescending(x => x.ID);
return fileDocuments;
我试图将 where 子句分成一个 func:
Func<SupplierInvoiceHeader, HelpDeskFault, PpmScheduleLineEntity, DocumentUploadEntity, bool> getJobWhereClause = (invoice, helpDeskFault, ppmScheduleLine, doc) =>
{
if (!string.IsNullOrEmpty(jobSearchParams.PIR) && string.IsNullOrEmpty(jobSearchParams.StoreName))
{
return invoice.PurchaseInvoiceReference == jobSearchParams.PIR;
}
if (string.IsNullOrEmpty(jobSearchParams.PIR) && !string.IsNullOrEmpty(jobSearchParams.StoreName))
{
return helpDeskFault.Store.Name.Contains(jobSearchParams.StoreName) || doc.Store.Name.Contains(jobSearchParams.StoreName) || ppmScheduleLine.Store.Name.Contains(jobSearchParams.StoreName);
}
return invoice.PurchaseInvoiceReference == jobSearchParams.PIR && (helpDeskFault.Store.Name.Contains(jobSearchParams.StoreName) || doc.Store.Name.Contains(jobSearchParams.StoreName) || ppmScheduleLine.Store.Name.Contains(jobSearchParams.StoreName));
};
我收到以下错误消息:
测试方法 IntegrationTests.Services.DocumentUploadServiceTests.Should_Search_By_PIR 抛出异常:System.NotSupportedException:LINQ 表达式 LINQ to Entities 不支持节点类型“Invoke”。
这是有道理的,因为没有从 func 到 sql 的直接转换,但是有没有办法可以创建一个表达式来实现我所追求的?
【问题讨论】:
-
只需将该变量声明为 Expression
>,而不是纯 Func -
我已经尝试过了,但在进行实际相等性检查时出现编译器错误:无法将带有语句体的 lambda 表达式转换为表达式树。
-
是的,我错过了它不是 lambda 表达式。您可以将其转换为带有“?:”运算符的单个语句吗?
-
如果我这样做,我会失去可读性。我需要阅读表达式树
-
LinqKit 是你所需要的
标签: c# entity-framework linq entity-framework-4