LINQ to SQL:左边连接一个表并计算平均值

时间:2014-03-21 22:16:37

标签: sql sql-server linq sql-to-linq-conversion

我正在尝试在LINQ to SQL中编写以下查询。该表包含用户排列的会话列表,该查询计算每个用户的连续会话之间的平均时间量。它使用左连接,因此只有一个会话的用户具有NULL值。

SELECT t1.workerId, AVG(DATEDIFF(s, t1.endTime, t2.startTime)) 
FROM e_userLongSessions t1 
LEFT JOIN e_userLongSessions t2 
ON t1.workerId = t2.workerId AND t1.sessionNum = t2.sessionNum - 1
GROUP BY t1.workerId
ORDER BY t1.workerId

根据问题LINQ to SQL Left Outer JoinHow to do joins in LINQ on multiple fields in single join,我收到了以下问题:

from s1 in gzClasses.e_userLongSessions
join s2 in gzClasses.e_userLongSessions
    on new {w = s1.workerId, n = s1.sessionNum} equals new {w = s2.workerId, n = s2.sessionNum - 1}
    into joined
from s2 in joined.DefaultIfEmpty(null)
group new {s1, s2} by s1.workerId into g                   
select g.Average(e => e.s2 == null ? (double?) null : (e.s2.startTime - e.s1.endTime).TotalSeconds);

我收到了Unsupported overload used for query operator 'DefaultIfEmpty'条消息。有什么建议吗?

1 个答案:

答案 0 :(得分:2)

您的LINQ查询的结构与T-SQL查询的结构不同。具体来说,您只在分组中包含s。事实上,s以误导的方式命名。它应该是s2。包括两者:

from s1 in gzClasses.e_userLongSessions                    
join s2 in gzClasses.e_userLongSessions
    on new {w = s1.workerId, n = s1.sessionNum} 
equals new {w = s2.workerId, n = s2.sessionNum - 1}
    into joined                    
from s2Null in joined.DefaultIfEmpty()                    
group new {s1, s2Null} by s1.workerId into g                    
orderby g.Key // workerId
select g.Average(e => (e.s2Null.startTime - e.s1.endTime).TotalSeconds);

现在,您可以在聚合中使用两个表中的数据。我不认为您的两个查询都考虑到s2.startTime可以为空。但这是一个不是问题的错误。