如何在Entity Framework中加入两个多对多的表?

时间:2013-01-16 20:34:00

标签: entity-framework many-to-many

我想要加入一些表:

  • 用户
  • 的UserRole
  • WorkflowRoles
  • 作用
  • 工作流

我想要生成的等效sql类似于

select * from Users u
inner join UserRoles ur on u.UserId = ur.UserId
inner join WorkflowRoles wr on wr.RoleId = ur.RoleId
inner join Workflow w on wr.WorkflowId = w.Id
where u.Id = x

我希望根据用户在一个查询中的角色来获取用户所属的所有工作流程。我发现你可以得到这样的结果:

user.Roles.SelectMany(r => r.Workflows)

但这会为每个角色生成一个明显不太理想的查询。

有没有一种正确的方法来做到这一点,而不必诉诸于生成视图或编写直接sql等黑客攻击?

3 个答案:

答案 0 :(得分:7)

您可以尝试以下两个查询:

这个更易读,我想:

var workflows = context.Users
    .Where(u => u.UserId == givenUserId)
    .SelectMany(u => u.Roles.SelectMany(r => r.Workflows))
    .Distinct()
    .ToList();

Distinct因为用户可以有两个角色,这些角色可能包含相同的工作流程。如果没有Distinct重复的工作流程,则会返回。)

但是这个表现更好,我相信:

var workflows = context.WorkFlows
    .Where(w => w.Roles.Any(r => r.Users.Any(u => u.UserId == givenUserId)))
    .ToList();

答案 1 :(得分:1)

所以事实证明你选择的顺序有所不同:

user.Select(x => x.Roles.SelectMany(y => y.Workflows)).FirstOrDefault()

答案 2 :(得分:0)

没有机会测试这个,但它应该有效:

Users.Include(user => user.UserRoles).Include(user => user.UserRole.WorkflowRoles.Workflow) 

如果上述内容不正确,那么您是否可以发布课程结构?