如何在 LINQ to entities 中执行带有附加过滤的左连接?
How to perform a left join with an additional filtering in LINQ to entities?
我有好几个table,主要的一个叫DefectRecord
,其他的叫DefectArea
,DefectLevel
...等等还有一个叫DefectAttachment
。这个问题是关于将 DefectRecord
与其他 table 加入以获得一个 ViewModel 以供进一步使用。我面临的困难部分是 DefectAttachment
table.
DefectRecord
与 DefectAttachment
具有一对多关系。虽然一个缺陷记录可能根本没有附件,但可能有多个附件。
从逻辑上讲,我尝试在 DefectRecord
和 DefectAttachment
之间执行左连接,但还有一个要求:
- 如果有多个附件,select只有最旧的(即最旧的
最旧的
CreatedDate
字段值)
我被这个要求困住了,我如何使用 LINQ-to-Entities 执行此操作?下面是我现在的代码:
var ret = (from dr in defectRecordQuery
join ft in filterQuery on dr.FilterID equals ft.FilterID
join l in levelQuery on dr.LevelID equals l.LevelID
join a in attachmentQuery on dr.DefectRecordID equals a.DefectRecordID into drd
from g in drd.DefaultIfEmpty()
select new DefectRecordViewModel
{
DefectRecordCode = dr.Code,
DefectAttachmentContent = g == null ? null : g.FileContent,
LookupFilterName = ft.FilterName,
}).ToList();
*Query 变量是 IQueryable
对象,它获取相应 table 的完整列表。
按 Code
和 FilterName
对结果进行分组,然后对于内容采用组中日期最早的项目的内容
var ret = (from dr in defectRecordQuery
join ft in filterQuery on dr.FilterID equals ft.FilterID
join l in levelQuery on dr.LevelID equals l.LevelID
join d in attachmentQuery on dr.DefectRecordID equals d.DefectRecordID into drd
from g in drd.DefaultIfEmpty()
group g by new { dr.Code, ft.FilterName } into gg
select new DefectRecordViewModel
{
DefectRecordCode = gg.Key.Code,
DefectAttachmentContent = gg.OrderByDescending(x => x.CreateDateTime).FirstOrDefault() == null? null: gg.OrderByDescending(x => x.CreateDateTime).FirstOrDefault().FileContent,
LookupFilterName = gg.Key.FilterName,
}).ToList();
如果使用 C# 6.0 或更高版本,您可以:
DefectAttachmentContent = gg.OrderByDescending(x => x.CreateDateTime)
.FirstOrDefault()?.FileContent,
我有好几个table,主要的一个叫DefectRecord
,其他的叫DefectArea
,DefectLevel
...等等还有一个叫DefectAttachment
。这个问题是关于将 DefectRecord
与其他 table 加入以获得一个 ViewModel 以供进一步使用。我面临的困难部分是 DefectAttachment
table.
DefectRecord
与 DefectAttachment
具有一对多关系。虽然一个缺陷记录可能根本没有附件,但可能有多个附件。
从逻辑上讲,我尝试在 DefectRecord
和 DefectAttachment
之间执行左连接,但还有一个要求:
- 如果有多个附件,select只有最旧的(即最旧的
最旧的
CreatedDate
字段值)
我被这个要求困住了,我如何使用 LINQ-to-Entities 执行此操作?下面是我现在的代码:
var ret = (from dr in defectRecordQuery
join ft in filterQuery on dr.FilterID equals ft.FilterID
join l in levelQuery on dr.LevelID equals l.LevelID
join a in attachmentQuery on dr.DefectRecordID equals a.DefectRecordID into drd
from g in drd.DefaultIfEmpty()
select new DefectRecordViewModel
{
DefectRecordCode = dr.Code,
DefectAttachmentContent = g == null ? null : g.FileContent,
LookupFilterName = ft.FilterName,
}).ToList();
*Query 变量是 IQueryable
对象,它获取相应 table 的完整列表。
按 Code
和 FilterName
对结果进行分组,然后对于内容采用组中日期最早的项目的内容
var ret = (from dr in defectRecordQuery
join ft in filterQuery on dr.FilterID equals ft.FilterID
join l in levelQuery on dr.LevelID equals l.LevelID
join d in attachmentQuery on dr.DefectRecordID equals d.DefectRecordID into drd
from g in drd.DefaultIfEmpty()
group g by new { dr.Code, ft.FilterName } into gg
select new DefectRecordViewModel
{
DefectRecordCode = gg.Key.Code,
DefectAttachmentContent = gg.OrderByDescending(x => x.CreateDateTime).FirstOrDefault() == null? null: gg.OrderByDescending(x => x.CreateDateTime).FirstOrDefault().FileContent,
LookupFilterName = gg.Key.FilterName,
}).ToList();
如果使用 C# 6.0 或更高版本,您可以:
DefectAttachmentContent = gg.OrderByDescending(x => x.CreateDateTime)
.FirstOrDefault()?.FileContent,