2015-05-29 180 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 
    };