您好我正在尝试在c#中加入两个表。加入代码如下。问题是,当tourid
中的tb_abc
为空值时,则不包括列表中tb_abc
的该行。
return (from p in context.tb_abc
from o in context.tb_Second
where o.id==p.tourId
where p.driverId == driverId
select new abcBean
{
id=p.id,
name=o.name
}).ToList<abcBean>();
谁能告诉我我做错了什么
答案 0 :(得分:4)
您没有在该查询中进行内部联接。您正在进行交叉连接,其中您有两个表,并将每个记录连接到每个其他记录。
如果要包含在其中一个约束上返回null的行,则需要左外连接。
return (from p in tb_abc
join o in tb_Second on p.tourId equals o.id into po
where p.driverId == driverId
from subpo in po.DefaultIfEmpty()
select new abcBean
{
id=p.id,
name=(subpo == null ? String.Empty : subpo.Name)
}).ToList();
考虑这两个sql语句:
第一个交叉连接:
select id, name
from tb_abc o,
tb_Second p
where
o.id = p.tourID
and p.driverID = @driverID
第二个左外连接:
select id, name
from tb_abc o
LEFT OUTER JOIN tb_Second p on o.id = p.tourID
where
p.driverId = @driverID
第二个将为您提供一组记录,其中包括o.id。
的空值第一个会给你一些你很少想要的Cartesian product。
Linq的DefaultIfEmpty()
将默认值(null)放入记录中,如果它没有找到一方的匹配项,那么它的行为类似于左外连接。
答案 1 :(得分:0)
您可以使用左外连接
return (from p in context.tb_abc
join o in context.tb_Second on o.id==p.tourId into gt
where p.driverId == driverId
from subsecond in gt.DefaultIfEmpty()
select new abcBean
{
id=p.id,
name=(subsecond == null ? String.Empty : subsecond.Name)
}).ToList<abcBean>();