2015-02-06 148 views
4

問題陳述:無法SQL查詢轉換爲LINQ查詢爲左外連接

我想轉換我的SQL到LINQ查詢的一個,但我無法得到需要的結果,我需要。任何人都可以向我建議我應該怎麼做?

SQL查詢:

SELECT AssetTagging.AssetID, AssetTagging.AssetDescription, [Return].RequestStatus 
FROM AssetTagging 
LEFT OUTER JOIN [Return] ON AssetTagging.AssetID = [Return].AssetID 
LEFT OUTER JOIN Issue ON AssetTagging.AssetID = Issue.AssetID 
WHERE (Issue.AssetID IS NULL) OR ([Return].RequestStatus = 'Approved') 

LINQ查詢我使用的是:

var result = (from at in db.AssetTagging.AsEnumerable() 
        join r in db.Return on at.AssetID equals r.AssetID 
        orderby at.AssetID 
        where !db.Issue.Any(issue=>issue.AssetID==at.AssetID) || r.RequestStatus=="Approved" 
        select new globalTestModel 
        { 
        model1=at 
        }).ToList(); 


//I know that in Linq query I'm using Inner join instead of Left Join,but i'm getting error if i use left join instead of inner join? 

我在做什麼錯?

任何建議獲得像Linq希望的查詢查詢?

資產標籤表:

enter image description here

問題表:

enter image description here

返回表:

enter image description here

所需的輸出:

enter image description here

+0

的可能重複[LINQ to SQL的左外連接(http://stackoverflow.com/questions/700523/linq-to-sql-left-outer-join) – vittore 2015-02-06 15:05:22

+0

@vittore:但是什麼鏈接你分享我前面提到的轉換我的內部連接到左外部連接,但它給錯誤像對象引用未設置爲一個對象的實例。我已經改變它作爲'加入r在db.Return at.AssetID等於r。在t.DefaultIfEmpty()'和在哪裏條件'rt.RequestStatus ==「Approved」''rt中將AssetID轉換爲t。'我認爲條件給出了錯誤 – 2015-02-06 15:18:10

+0

我沒有看到你引用鏈接的地方註釋。來自鏈接主題的示例告訴您使用'將db.Return加入at.AssetID等於r.AssetID加入到joinedReturns'中。 – vittore 2015-02-06 16:38:15

回答

1

你需要做的是這樣的:

var result = from at in db.AssetTagging 
       join r in db.Returns on at.AssetID equals r.AssetID into a 
       from returns into a.DefaultIfEmpty() 
       join i in db.Issues on at.AssetID equals I.AssetID into b 
       from issues into b.DefaultIfEmpty() 
       where issues.AssetID != null || returns.RequestStatus == "Approved" 
       select new 
        { 
         AssetID = at.AssetID, 
         AssetDescription = at.AssetDescription, 
         Status = returns != null ? returns.RequestStatus : null 
        }.ToList(); 
+0

這會給對象引用錯誤,因爲問題和返回值爲空 – 2015-02-15 06:35:20

+0

@Vishal I Patil I am檢查null,所以它不應該拋出異常 – 2015-02-15 13:40:02

2

您需要刪除.AsEnumerable(),因爲你希望你的查詢被翻譯爲sql。現在它將使用linq-to-objects,如果您使用的是與linq-to-object的左連接,則需要檢查空引用異常。 rt可能爲空,因此rt.RequestStatus會引發異常。

*我認爲rt應該r在你的榜樣

無法投射到現有的實體,所以你需要改變你的選擇:

select new PocoClass 
{ 
    model1=at 
} 

//New class definition 
public PocoClass 
{ 
    public AssetTagging model1 { get; set; } 
} 
+0

是的,這是r不是rt,我已經更新了我的問題,你可以請再次檢查一遍。我需要它作爲.AsEnumerable因爲我綁定Enumerable模型到我的視圖。 – 2015-02-06 14:56:48

+0

嗨,我檢查.AsEnumerable不是問題。你可以幫我在資產標記和返回表之間使用左連接而不是內連接。替代內連接的左連接我已經使用'join r in db.Return on at .AssetID等於r.AssetID從t.DefaultIfEmpty()rt中的t.DefaultIfEmpty()',但它給出了錯誤 – 2015-02-06 15:06:03

+0

它給出了錯誤,因爲對象引用沒有設置爲僅用於左外部連接的對象的實例而不是用於內部連接。出現了什麼問題?? – 2015-02-06 15:24:53

1

試試我假設以下你仍然想要r的情況爲空,除非r不爲空並且請求狀態=批准。

在檢查請求狀態之前,您必須檢查以確認r!= null,並且當r爲空時您仍然需要包含以獲取完整的結果集。我沒有測試過這個,但是這應該會讓你朝正確的方向發展。

祝你好運。

var result = (from at in db.AssetTagging 
       join r in db.Return.DefaultIfEmpty() 
       on at.AssetID equals r.AssetID 
       join i in db.Issue.DefaultIfEmpty() 
       on at.AssetID equals i.AssetID 
       where 
       (r == null || (r!=null && r.RequestStatus == "Approved")) 
       || i == null 
       select new { 
       at.AssetID, 
       at.AssetDescription, 
       IssueID = (i!=null) ? i.IssueID : null), 
       ReturnID = (r!=null) ? r.ReturnID: null), 
       ReturnStatus = (r!=null) 
        ? r.ReturnStatus 
        : null}).ToList(); 
+0

嗨,它會產生AssetTagging表中的所有行,我需要根據'i.AssetID IS NULL'和'r.RequestStatus ='Approved''過濾它,如何在LINQ中實現此操作 – 2015-02-13 09:15:31

+0

請檢查我的問題i已更新 – 2015-02-15 06:58:43

+0

根據您的新要求修改 – 2015-02-16 19:43:56

0

下面是完整的查詢

var result = (from assetTagging in db.AssetTagging 
       join return0 in db.Return on assetTagging.AssetID equals return0.AssetID into returns 
       from return0 in returns.DefaultIfEmpty() 
       join issue in db.Issue on assetTagging.AssetID equals issue.AssetID into issues 
       from issue in issues.DefaultIfEmpty() 
       where issue.AssetID == null || return0.RequestStatus == "Approved" 
       select new 
       { 
        assetTagging.AssetID, 
        assetTagging.AssetDescription, 
        return0.RequestStatus 
       }).ToList(); 
+0

這會給出對象引用錯誤,因爲問題和returno爲空... !!! – 2015-02-15 06:34:35

1

嘗試像以下:

from at in db.AssetTagging 
join r in db.Return on at.AssetID equals r.AssetID into res1 
from atr in res1.DefaultIfEmpty() 
join i in db.Issues on i.AssetID==at.AssetID into res2 
from obj in res2.DefaultIfEmpty() 
select at 
where i.AssetID == null || r.RequestStatus equals "Approved" 

只是要兩次左外加入,然後做什麼過濾條件ñ。

也有第一次看this關於使用linq的左外連接的msdn文章。

1

我知道這不完全是你要求的,但它可能是有用的無論如何。

如果你有權訪問數據庫來執行SQL查詢,我會建議創建一個視圖。然後,您可以像使用表一樣將視圖拖放到DBML文件中,並且在C#代碼中使用更簡單的Linq表達式。

CREATE VIEW [Asset_Issue_Return_Joined] AS 
SELECT AssetTagging.AssetID, AssetTagging.AssetDescription, [Return].RequestStatus 
FROM AssetTagging 
LEFT OUTER JOIN [Return] ON AssetTagging.AssetID = [Return].AssetID 
LEFT OUTER JOIN Issue ON AssetTagging.AssetID = Issue.AssetID 
WHERE (Issue.AssetID IS NULL) OR ([Return].RequestStatus = 'Approved')