2015-05-29 178 views
2

我寫了一個LINQ lambda查詢,到目前爲止它返回所有沒有關聯的培訓行的工作正常的人員。我現在需要修改我的where子句以將管理員標識加入管理員表到員工身上。LINQ Lambda左連接與內部連接

我有點不確定如何修改這個左連接lambda以包含內連接。如果任何人都能指出我將會非常感激的正確方向。

var managerId = 1; 

    var query = db.staff 

       .GroupJoin(db.training, 
        s => s.id, 

        t => t.staff_id, 
        (s, t) => new {Staff = s, Training = t.FirstOrDefault()}) 

    //TODO: join manager.id on staff.manager_id 


      .Where(st => st.Training==null);//TODO: modify where clause && manager.id == managerId 

感謝

+0

感謝您的答覆,我想往下走查詢表達式路線,但想看看是否有人能幫助我的Lambda表達式爲學習超過任何東西 –

+0

你可以簡單地添加'staff.Where(s => s.managerId == managerId)'。但我認爲你應該使用導航屬性,不要加入。如果您需要幫助,請展示班級模型。 –

回答

4

使用Join方法執行內部連接。我覺得您的查詢應該是這樣的:

var query = db.staff 
       .GroupJoin(db.training, 
         s => s.id, 
         t => t.staff_id, 
         (s, t) => new { Staff = s, Training = t.FirstOrDefault() }) 
       .Join(db.manager, 
        gj => gj.Staff.manager_id, 
        m => m.id, 
        (gj, m) => new { Staff = gj.Staff, Training = gj.Training, Manager = m }) 
       .Where(st => st.Training == null 
         && st.Manager.id == managerId); 
+1

不確定,但在where子句之後執行內連接可能更有效,這樣它就不會打擾加入由左連接過濾掉的記錄。你可以有多個where子句(如,GroupJoin(training),Where(Training == null),Join(manager),Where(Manager.Id == managerId)。我想這取決於你使用的LINQ提供者... –

+0

這個lambda表達式返回了我期待的結果 - 完美!我將根據您的評論來看看查詢的效率。非常感謝!:) –

+0

你會如何做到這一點' gj => gj.Staff.manager_id'改爲使用培訓代替?像這樣'gj => gj.Training。' –

1

你可以做以下的(我還沒有使用的方法鏈接語法,使其更具可讀性IMO):

var query = from s in db.staff 
      join m in db.manager on s.manager_id equals m.id 
      join t in db.training on s.id equals t.staff_id into tr 
      from training in tr.DefaultIfEmpty() 
      select new 
      { 
       Staff = s, 
       Training = training 
      }; 
1

喜歡這也許:

var query = from s in db.staff 
    join m in db.manager on s.manager_id equals m.id 
    from t in db.training 
     .Where(w=>w.staff_id==s.id).DefaultIfEmpty() 
    select new 
    { 
     Staff = s, 
     Training = training 
    };