有人能帮忙吗?
我有 1 个类,基本上它包含成员,在该类中是一个列表。
我在列表中的成员也...所以基本上是这样的,
我有 2 个成员,每个成员都有多个 session 。
我希望只返回每个成员 1 个 session 。
我做了一个LINQ查询,当然不行...
我想我需要做一个 self 加入,有什么想法吗?
基本上我的错误是我的子查询自连接中不存在 m。
var sessions =
from m in this.members
join s in
(
from se in m.Sessions
group se by se.Name into g
select new {Name = g.Key, SessioEndTime = g.Max(a=>a.SessioEndTime)}
)
on m.Name equals s.Name
select new { MemberName = m.Name, SessionTime = s.SessioEndTime}
我将不胜感激任何人的反馈。
提前致谢。
编辑
好的,我设法像下面那样做了,但这是最好的方法吗?
var sessions =
from m in this.members
let sn = m.Sessions.OrderByDescending(a => a.SessionEndTime).FirstOrDefault()
select new { MemberName = m.Name, SessionTime = sn.SessioEndTime}
这样 sn 包含 1 条记录,但我可以访问所有属性...
但这是使用 LET 的最佳方式吗?
谢谢。
最佳答案
除非我遗漏了什么你需要这个,不是吗?
var sessions =
from m in members
select new {
MemberName = m.Name,
SessionTime = m.Sessions.Max(s => s.SessioEndTime)
};
您必须改变您对 LINQ 查询的思考方式,更多地从对象的角度而不是从 SQL 实现的角度来思考。我需要什么?我需要所有成员,每个成员都有其最新的 session 结束时间,然后据此采取行动。
编辑:
您使用的 let 选项没问题,请记住,如果成员的 session 列表为空,FirstOrDefault
将返回 null,然后 sn.SessionEndTime 命中 null 引用。另一方面,如果您确定每个成员至少有一个 session ,请改用 First
或聚合。
也不要在 let 中使用 FirstOrDefault()
,它会弄乱 LINQ 并阻止它把它绑定(bind)到 master(导致每个 master 有一个单独的 SQL 查询来检测丢失的子集), let 的可用查询是:
from m in Members
let sn = m.Sessions.Max(s => s.SessioEndTime)
select new { MemberName = m.Name, SessionTime = sn};
from m in Members
let sn = m.Sessions.OrderByDescending(a => a.SessioEndTime).First()
select new { MemberName = m.Name, SessionTime = sn.SessioEndTime};
至于ordering vs Max聚合,两个查询都会生成一个子查询:
-- MAX
SELECT [t0].[Name] AS [MemberName], (
SELECT MAX([t1].[SessioEndTime])
FROM [Session] AS [t1]
WHERE [t1].[memberId] = [t0].[id]
) AS [SessionTime]
FROM [Member] AS [t0]
GO
-- ordering
SELECT [t0].[Name] AS [MemberName], (
SELECT [t2].[SessioEndTime]
FROM (
SELECT TOP (1) [t1].[SessioEndTime]
FROM [Session] AS [t1]
WHERE [t1].[memberId] = [t0].[id]
ORDER BY [t1].[SessioEndTime] DESC
) AS [t2]
) AS [SessionTime]
FROM [Member] AS [t0]
在 SessioEndTime 上使用降序索引,排序脚本大约慢两倍(您可以获取这些执行计划以自行检查),没有索引它大约慢 5 倍。
关于LINQ: 自连接查询,如何实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5026970/