有人可以将它转换为C#LINQ吗?在列表中查找缺失的项目<T>
SELECT *
FROM vf
LEFT JOIN dbvf
ON vf.sid =dbvf.sid
AND vf.cid =dbvf.cid
WHERE dbvf.sid IS NULL
两个VF和dbvf是List<T>
。 sid和cid是整数。
我想要做的是在vf中找到在dbvf中缺少的项目。
有人可以将它转换为C#LINQ吗?在列表中查找缺失的项目<T>
SELECT *
FROM vf
LEFT JOIN dbvf
ON vf.sid =dbvf.sid
AND vf.cid =dbvf.cid
WHERE dbvf.sid IS NULL
两个VF和dbvf是List<T>
。 sid和cid是整数。
我想要做的是在vf中找到在dbvf中缺少的项目。
试试这个
var ret = from p1 in vf
join p2 in dbvf
on p1.sid equals p2.sid && p1.cid equals p2.cid into g
from p2 in g.DefaultIfEmpty()
where p2 == null
select new {vf=p1, dbvf=p2}
或这种简单
vf.Except(dbvf);
我实现基于http://msdn.microsoft.com的IEquatable后/en-us/library/bb300779.aspx,vf.Except(dbvf);工作:) – developer747
好...简单而原始:) – innovia
@Tiz,你的连接语法不完全正确。你只能有一个'equals','equals'左边的表达式只能引用你的'p1'范围变量;类似地,右边的表达式只能引用你的'p2'范围变量。解决这个连接问题最简单的方法就是使用匿名类型,就像我在答案中所做的那样。 – devgeezer
类似下面
from dbvf in dbvfs
from vf in vfs
where vf.sid == dbvf.sid && vf.cid == dbvf.cid
where dbvf.sid == null
select new { dbvf = dbvf, vf = vf}
dbvf.sid是一个int。所以它会抛出一个错误“Warning as Error:表达式的结果总是'false',因为'int'类型的值永远不会等于'int'类型的'null'。 “ – developer747
@ developer747这是说,dbvf.sid == null不代表什么,这个值是否可以为空? –
不可空值。在SQL中,我该怎么做。 – developer747
尝试是这样的:
var query =
from v in vf
join d in dbvf
on new { v.sid, v.cid }
equals new { d.sid, d.cid } into gj
where !gj.Any()
select v;
如前所述,您的目的是做一个“除外”。我已经回答了如何用左连接语义来做到这一点。
var query =
from v in vf
join d in dbvf
on new { v.sid, v.cid }
equals new { d.sid, d.cid } into gj
from d in gj.DefaultIfEmpty()
where d == null
select v;
这里使用的匿名类型似乎是黑魔法的门外汉。然而,编译器创建匿名类型(实际上它只是一种类型),其具有名为sid
和cid
的两个属性,并提供Equals
和GetHashCode
的实现,Join
将在其实现中使用。我在into
子句中选择gj
是因为引入into
会导致编译器执行GroupJoin
而不是定期调用Join
。
我可以添加到查询通过添加from d in gj.DefaultIfEmpty()
条款,恢复了先前由into
条款隐藏在d
范围变量得到类似的感觉,你的SQL样品。现在我可以添加where d == null
子句,与原始SQL几乎达到同等水平。
这个匿名类型介绍是您可能需要再次使用的东西,如果您想要通过sid
和cid
这两个组执行其他操作(例如组)。
如果dbfv.sid为null,为什么它甚至在连接标准中?另外,linqpad是你的朋友! –