2013-10-31 95 views
3

嗨,我想在c#中連接兩個表。下面給出了連接代碼。問題是當touridtb_abc中有空值時,那麼在列表中將不包括來自tb_abc的該行。Linq查詢連接不起作用

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

[當有人回答我的問題,我應該怎麼辦?(http://meta.stackoverflow.com/help/someone-answers) – paqogomez

回答

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()將缺省值(空)放入記錄中,如果它找不到一側的匹配,則它的行爲與左外連接相似。

+0

我的交叉連接示例不是真正的交叉連接,因爲我們在where子句中加入表,所以存在一些限制。沒有約束條件,它使用sql89語法進行交叉連接。 – paqogomez

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>(); 
+0

,因爲它不會編譯,所以你首先使用你的o.id變量,並在聯機中使用'='。您需要將其更改爲「p.tourId等於o.id」 – paqogomez