2011-12-08 110 views
2

我第一次使用實體框架,所以我不知道我是否正確執行此操作。Linq to Entities多對多連接

我有4個表:

CustomerOrder 
------------ 
ID, StaffID, DeptID, Status, other columns... 

Staff 
------------ 
StaffID, other columns... 

StaffDept 
------------ 
StaffID, DeptID - only 2 fields 

Dept 
------------ 
DeptID, other columns... 

一位工作人員可以屬於多個部門。 StaffDept表僅用於存儲此多對多關係。

我需要檢索的組合:

  • 所有客戶訂單是有「正在進行中」
  • 一個Status爲與當前工作人員在任何額外的記錄Status「進行中」
  • 任何額外的記錄與Status「進行中」,其中工作人員是與客戶訂單相同部門的成員。

例如,如果我有以下數據:

Staff 
----- 
1, Mr X, ... 
2, Mr Y, ... 

Dept 
----- 
1, Sales, ... 
2, Marketing, ... 

StaffDept 
----- 
1, 1 
1, 2 
2, 2 

CustomerOrder 
----- 
1, 1, 1, In Progress, ... 
2, 1, 1, Completed, ... 
3, 2, 2, In Progress, ... 
4, 2, NULL, In Progress, ... 

我想如果當前用戶爲#1,他們將看到客戶訂單1,2,3期待。用戶#2會看到2,3,4。

這裏是我到目前爲止的代碼:

from co in CustomerOrders 
where co.Status != "In Progress" 
    || co.StaffID == @CurrentStaffID 
    || (co.StaffID != @CurrentStaffID 
     && co.DeptID!= null 
     && Staffs.Where(x => x.StaffID == @CurrentStaffID).FirstOrDefault().Depts.Any(x => x.DeptID== co.DeptID)) 
select new CustomerOrderObject 
{ 
    Description = co.Description, 
    Amount = co.Amount, 
    ... 
} 

其工作原理,但ReSharper的抱怨說,FirstOrDefault()部分將在運行時拋出一個NULL例外。我已經用Linqpad中的#3用戶(它不存在)進行了測試,並且它沒有拋出錯誤 - 它只返回記錄2,這是我所期望的。 Resharper希望我在上述查詢之前將Staffs.Where(x => x.StaffID == 3).FirstOrDefault()拉出到單獨的查詢運行中,但我認爲這會讓它變慢?我真的不確定這個查詢是否是獲取數據的最快方法,因爲我是新來的linq實體,我一直在使用linq-to-sql。任何建議將不勝感激 - 我甚至不知道如何正確描述我試圖做的連接類型。

回答

2

由於您只是通過主鍵檢索Staff的成員,並且您知道該ID只有一名工作人員,因此應該用Single替換FirstOrDefault

Staffs.Single(x => x.StaffID == @CurrentStaffID).Depts.Any(x => x.DeptID== co.DeptID)) 

編輯1:

也許你可以稍微摺疊查詢:

StaffDept.Any(sd => sd.StaffId == @CurrentStaffID && sd.DeptID== co.DeptID) 

編輯2:

Staff.Any(x => x.StaffID == @CurrentStaffID && x.Depts.Any(d => d.DeptID == co.DeptID) 
+0

清楚,固定ReSharper的抱怨。之前我沒有這樣做的原因是Linqpad會拋出一個錯誤,指出「NotSupportedException:方法'Single'和'SingleOrDefault'只能用作最終的查詢操作,請考慮在這個實例中使用方法'FirstOrDefault'。這是最好的方式來做到這一點加入linq實體,但? – JumpingJezza

+0

@JumpingJezza看看直接用於'StaffDept'的查詢的第二個版本是否會更好。 – dasblinkenlight

+0

這就是奇怪的事情。在我導入數據庫的實體數據模型中,它刪除了'StaffDept'表,並在其中放入了多對多連接。我認爲這是一些智能框架的東西 – JumpingJezza