这是执行左外最有效的方式加入LINQ,如果我必须在开始和结束日期执行下列操作...如何编写一个LINQ查询,将子表过滤到特定时间段并汇总子表的结果?
- 筛选表2。
- 表1中的所有行都必须保留,即使表2的过滤没有返回任何行。
- 结果必须进行分组,以便表2中的列求和。
例如(示例代码变量名称因专有原因而更改),假设我有一个包含两个表的数据库。表1列出了具有建筑物代码,门ID和当前状态(打开或关闭)的门 - 建筑物代码和门ID是主键。表2列出了所有门的事件(一个事件是开放或关闭)加上一个时间戳。所以列是建筑代码,门ID,时间戳,打开,关闭。打开和关闭是相应事件的列中有1的整数。建筑密码和门ID两个表格之间存在外键关系。
对于我的查询,我需要返回所有唯一门的列表,包括当前的门状态以及所选时间段内所有开门和关门事件的总和。 即使在所选时间段内没有发生任何事件,也必须为每扇门返回条目。
下面是我能想到的最好的LINQ代码。它有效,但它看起来效率很低,很难理解。你如何使它更高效,更易于理解?
var query =
from doors in Context.Doors
join fevents in
(
from events in db.Events
where events.TimeStamp >= date1 && events.TimeStamp <= date2
select new { events.BuildingCode, events.DoorID, events.TimeStamp, events.Opening, events.Closing }
)
on new { doors.BuildingCode, doors.DoorID } equals { fevents.BuildingCode, fevents.DoorID }
into g1
from c in g1.DefaultIfEmpty()
group c by new
{
doors.BuildingCode,
doors.DoorID,
doors.DoorStatus
} into g2
select new
{
BuildingCode = g2.Key.BuildingCode,
DoorID = g2.Key.DoorID,
Status = g2.Key.DoorStatus
NumOpenings = g2.Sum(i => (i == null ? 0 : i.Opening)),
NumClosings = g2.Sum(i => (i == null ? 0 : i.Closing))
};
感谢您的回答@aducci。很有帮助。这让我以不同的方式思考问题。我已经发布了我的略有不同的答案作为其他人的参考。 –