链接到实体多对多连接

本文关键字:连接 实体 链接 | 更新日期: 2023-09-27 18:17:02

我第一次使用实体框架,所以我不确定我是否这样做是正确的。

我有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为"In Progress"的在职员工的额外记录
  • 任何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到sql。任何建议都将非常感激-我甚至不确定如何正确描述我正在尝试做的连接类型。

链接到实体多对多连接

由于您只是通过其主键检索Staff的成员,并且您知道该ID将只有一个工作人员,因此您应该将FirstOrDefault替换为Single

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)