我有一个SQL查询,其中包括一个左连接和一个分组 - 到目前为止一切顺利 - 我的麻烦源于其中一个连接条件不是直接的"等于",我迷失了LINQ的去向。
我知道多个连接条件通常涉及创建几个匿名对象并比较它们,但是当我在混合中添加"等于"和"大于"时,我不知道这如何应用。
如果我发明了 LINQ,我希望查询看起来像这样,但我知道我的连接条件中的"and"无效;
var query =
from csp in db.ChatSessionPersons
join cm in db.ChatMessages on
csp.ChatSessionId equals cm.ChatSessionId
and cm.Id > csp.LastReadChatMessageId
// (i know these should be the other way round,
// but for readability I present them like this!)
into j1
from j2 in j1.DefaultIfEmpty()
group j2 by csp.ChatSessionId into grouped
select new {
ChatSessionId = grouped.Key,
UnreadCount = grouped.Count(t => t.Id != null)};
有人有什么想法吗?
您可以将非相等条件转换为组联接结果上的 lambda Where
。
var query = from csp in db.ChatSessionPersons
join cm in db.ChatMessages on csp.ChatSessionId equals cm.ChatSessionId into cmj
select new {
ChatSessionId = csp.ChatSessionId,
UnreadCount = cmj.Where(cm => cm.Id > csp.LastReadChatMessageId).Count()
};
注意:我稍微修改了查询以删除如果您使用的是已对匹配结果进行分组的组联接,则不需要group by
,并删除左联接DefaultIfEmpty
,在处理具有类似 Count
的组联接时也不需要,除非您想在没有匹配项时返回 1 UnreadCount
, 在这种情况下,您应该将DefaultIfEmpty()
放在Count()
之前。
当然,您可以在子查询中使用查询理解:
var query = from csp in db.ChatSessionPersons
join cm in db.ChatMessages on csp.ChatSessionId equals cm.ChatSessionId into cmj
select new {
ChatSessionId = csp.ChatSessionId,
UnreadCount = (from cm in cmj where cm.Id > csp.LastReadChatMessageId select cm).Count()
};