C# Linq Left Join,其中right为null
linq相对较新,来自SQL。因此,我试图找出以下的左连接:C# Linq Left Join,其中right为null,c#,.net,linq,linq-to-sql,C#,.net,Linq,Linq To Sql,linq相对较新,来自SQL。因此,我试图找出以下的左连接: SELECT * from MASTER m LEFT JOIN CHILD C ON m.ID=C.MASTER_ID WHERE C.MASTER_ID is null 所以,通常情况下,这将返回主服务器中没有子服务器的所有记录。我发现了.DefualtIfEmpty(),但这并没有消除有子记录的主记录 var recs = MASTER.Where(x => !child.Any(y => m.Id ==
SELECT * from MASTER m
LEFT JOIN CHILD C
ON m.ID=C.MASTER_ID
WHERE C.MASTER_ID is null
所以,通常情况下,这将返回主服务器中没有子服务器的所有记录。我发现了.DefualtIfEmpty(),但这并没有消除有子记录的主记录
var recs = MASTER.Where(x => !child.Any(y => m.Id == c.MasterId));
我从以下几点开始:
var recs=from m in MASTER
from c in child
.where (mapping=>mapping.MasterId == m.Id)
.DefaultIfEmpty()
select new { MasterId = m.Id};
但那是我所能做的,我被卡住了。我假设.DefaultIfEmpty()不是我想要的。
注意:主表中有几百万行。孩子们的人数几乎相同。我之所以提到这一点,是因为它无法有效地收回所有记录等。理想情况下,生成的SQL将与我发布的SQL类似
谢谢大家。如果您使用的是EF,那么您可以使用代表子对象的导航属性获取没有子对象的主对象:
var result= from m in MASTER
where m.Children.Count()==0// or m.Any()
select m;
如果您想在linq中使用显式联接,可以尝试以下方法:
var recs=from m in MASTER
join c in child on m.Id equals C.MasterId into gj
where gj.Count()==0 // or gj.Any()
select m;
这将为您提供所有没有子项的主记录
var recs = MASTER.Where(x => !child.Any(y => m.Id == c.MasterId));
!任何
都将生成一个不存在
SQL语句,该语句将被转换为执行计划中的反半联接
,这是您可以获得的最好的检查类型。您可以使用Linq执行左外联接
var leftJoinResult = from m in MASTER join c in CHILD
on m.ID equals C.MASTER_ID
into a
from b in a.DefaultIfEmpty()
select new {MASTER = m,
CHILD = b};
然后删除有子记录的主记录
var result=leftJoinResult.where(x=>x.CHILD == null).select(y=>y.MASTER).ToList();
我也有同样的问题。此解决方案仅在子项中至少有一行时有效。行的ID不重要
var recs=from m in MASTER
from c in child
.where (mapping=>mapping.MasterId == m.Id)
.DefaultIfEmpty() into fullC
select new { MasterId = m.Id};
关键字进入起到了神奇的作用。添加它会显示所有行,以及那些在c中有空值的行。请参见msdn网站:我也喜欢这种方法,但我在这个特定项目中不使用EF。但是,我还有其他一些我确实使用过的,我将用这种方式处理这些项目。谢谢。我查看了它生成的SQL的查询计划,它看起来已经尽可能地优化了。现在有了几个位置合适的指数,我想我会成为黄金。谢谢