3

嗨,我正在尝试在 c# 中加入两个表。加入代码如下。问题是,当 in 有空值时,touridintb_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>();

谁能告诉我我做错了什么

4

2 回答 2

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 的空值。

第一个会给你一些你很少想要的笛卡尔积。

如果LinqDefaultIfEmpty()没有为一侧找到匹配项,则将默认值 (null) 放入记录中,因此它的行为类似于左外连接。

于 2013-10-31T19:48:49.230 回答
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>();
于 2013-10-31T19:48:51.100 回答