Return EF6 中多对多连接的一列 table

Return one column from a many-to-many join table in EF6

我需要在 EF6

的多对多关系中 return 连接 table 中的单个列
User { Id, Name}
Role { Id, Role}
UserToRole { UserId, RoleId}

这是一个简化的示例,但我需要从用户那里获取 RoleId (Role.Id) 的列表。

理想情况下,我会做类似

的事情
context.UserToRole.Where(x => x.UserId == id).Select(r => r.RoleId).ToList();

但 EF 似乎没有向我提供该连接 table 作为查询对象。

我知道我可以将所有角色作为对象拉下来,但在我的实际系统中它很宽 table 我想避免通过网络拉动所有数据和存入内存

更新

您可以尝试 context.Roles.SqlQuery("Select * from Roles where id in (select roleid from usertoroles where userid = @userid") 避免加载用户。


如果您的问题是将所有角色分配给特定用户,请按如下所示定义您的实体:

    public class User
    {
        public int Id { get; set; }
        public string UserName { get; set; }

        //Navigation Property
        public List<Role> Roles { get; set; }
    }

    public class Role
    {
        public int Id { get; set; }
        public string Name { get; set; }

        //Navigation Property
        public List<User> Users { get; set; }
    }

除非你想控制多对多 table 名称和列名(这很简单),否则你已经准备好了。

创建用户

User k = new User()
         {
             UserName = "Kishan",
             Roles = new List<Role>()
             {
                 new Role() { Name = "Supremo" }
             }
         }
context.Users.Add(u);
context.SaveChanges();
User r = new User()
         {
             UserName = "Rama",
             Roles = new List<Role>()
             {
                 context.Roles.Single(r => r.Name == "Supremo")
             }
         }
context.SaveChanges();

查找用户的角色

User u = context.Users.Single(u => u.UserName == "Kishan");
List<int> userRoleIdList = u.Roles.Select(r => r.Id).ToList();

如果您只需要 User 中的 RolesId,您可以执行此查询:

 int userId=1;
 var roleIds = db.Users.Where(u => u.Id == userId).SelectMany(u => u.Roles.Select(a=>a.Id));

这将生成这样的 sql 查询:

 {SELECT [Extent1].[Role_Id] AS [Role_Id]
  FROM [dbo].[UserRoles] AS [Extent1]
  WHERE [Extent1].[User_Id] = @p__linq__0}

如您所见,查询与您查找的相同。

关系应该已经存在:通常,如果您将多对多关系定义为双向集合,EF 会为您生成连接 table,这意味着您只需聪明地根据您可以看到的 tables 来设计您的 LINQ 查询(诚然,这有时会很棘手)。 (我从你的评论中得出 "EF doesn't seem to provide you the join table" 确实如此。)

因此,根据您给出的示例,它会是这样的:

context.Users.Where(u => u.Id == id).Single().Roles.Select(r => r.Id);

需要注意的是,如果没有 UserId==id 一起找到,或者如果找到多个(因此 Id 不是键),这将抛出。然而,这通常正是您想要的此类查找。