链接到实体多对多连接
本文关键字:连接 实体 链接 | 更新日期: 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)