如何编写涉及多对多关系的EF查询

时间:2011-08-23 16:27:09

标签: c# .net entity-framework entity-framework-4.1

我很擅长使用实体框架,但是我无法理解如何编写使用多对多关系的查询。我有3个实体。 角色用户安全角色可以有多个 Securables 安全可以分配给多个角色角色可以包含多个用户用户可以包含多个角色

我的问题是:我如何编写一个查询,为给定的用户ID提供了明确的Securables列表?

这是我的模型,EF会自动为我创建链接表。

public class SecurityContext : DbContext
{
    public DbSet<User> Users { get; set; }

    public DbSet<Role> Roles { get; set; }

    public DbSet<Securable> Securables { get; set; }
}

public class User 
{
    public Guid UserId { get; set; }

    public string Forename { get; set; }

    public string Surname { get; set; }

    public string Username { get; set; }

    public string Password { get; set; }

    public virtual ICollection<Role> Roles { get; set; }
}

public class Securable
{
    public Guid SecurableId { get; set; }

    public string Name { get; set; }

    public virtual ICollection<Role> Roles { get;set;}
}

public class Role
{
    public Guid RoleId { get; set; }

    public string Name { get; set; }

    public virtual ICollection<Securable> Securables { get; set; }

    public virtual ICollection<User> Users { get; set; }
}

2 个答案:

答案 0 :(得分:2)

未经测试,但在我的脑海中,它将是这样的:

var context = new DbContext();
var result = context.Securables
                    .Where(s => s.Roles
                                 .Any(r => r.Users
                                            .Any(u => u.UserId = userId)))
                    .Distinct();

答案 1 :(得分:1)

喜欢这个吗?

User user = ...;
IEnumerable<Securable> securablesForUser =
  user.Roles.SelectMany(x => x.Securables).Distinct();

<强>更新: -

在一个真正成为性能瓶颈的项目之后,我进行了更深入的调查,发现以下LINQ查询生成了最好的SQL(对于我们的数据): -

IEnumerable<Securable> securablesForUser =
    context.Users.Where(x => x.UserId == userId)
                 .SelectMany(x => x.Roles)
                 .SelectMany(x => x.Securables)
                 .Distinct();

这将在翻译的SQL语言中使用INNER JOIN: -

IEnumerable<Securable> securablesForUser = context.Securables.Where(
    x => x.Roles.Any(y => y.Users.Any(z => z.UserId == userId))).Distinct();

使用WHERE EXISTS在我们的基准测试中比查询两次。

与往常一样,如果您有性能问题,我建议进行性能分析。您的数据结果可能有所不同。 如果您不关心配置文件,那么您并不在乎优化!