Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
LINQ:自连接查询,如何实现?_Linq_Linq To Sql_Linq To Objects_Self Join - Fatal编程技术网

LINQ:自连接查询,如何实现?

LINQ:自连接查询,如何实现?,linq,linq-to-sql,linq-to-objects,self-join,Linq,Linq To Sql,Linq To Objects,Self Join,有人能帮忙吗 我有一个类,基本上它包含成员,在这个类中有一个列表 我名单上的成员也。。。所以基本上是这样的 我有2名成员,每个成员有若干次会议 我只想让每位成员参加一次会议 我已经做了一个LINQ查询,但它当然不起作用 我想我需要做一个自我连接,有什么想法吗 基本上我的错误是我的子查询自连接中不存在m var sessions = from m in this.members join s in ( from se in m.Sessions

有人能帮忙吗

我有一个类,基本上它包含成员,在这个类中有一个列表

我名单上的成员也。。。所以基本上是这样的

我有2名成员,每个成员有若干次会议

我只想让每位成员参加一次会议

我已经做了一个LINQ查询,但它当然不起作用

我想我需要做一个自我连接,有什么想法吗

基本上我的错误是我的子查询自连接中不存在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实现的角度来思考。我需要什么?我需要所有成员,每个成员都有其最新的会议结束时间,然后采取行动

编辑: 您使用的let选项是可以的,请记住,如果成员的会话列表为空,则
FirstOrDefault
将返回null,然后sn.sessionedTime将命中null引用。另一方面,如果您确定每个成员至少有一个会话,请先使用
或聚合。
另外,不要在let中使用
FirstOrDefault()
,它会弄乱LINQ并阻止它将其绑定到主机(导致每个主机都有一个单独的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 aggregation,两个查询都将生成一个子查询:

-- 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]

如果SessionEndTime上有一个降序索引,则排序脚本的速度大约慢两倍(您可以自己检查这些脚本的执行计划),如果没有索引,则速度大约慢五倍。

是的,谢谢,让我们看看我是否正确,我使用了“let”,这样可以吗?还是有更好的办法?现在我让sn=m.Sessions.OrderByDescending(a=>a.SessionEndTime).FirstOrDefault(),现在我有了会话的完整记录,所以我可以执行sessiontime=sn.SessionEndTime以及其他属性。。