繁体   English   中英

从EF6中的多对多联接表返回一列

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

我需要以EF6中的多对多关系从联接表返回单个列

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似乎没有向我提供该连接表作为要查询的对象。

我知道我可以将所有角色都作为对象拉下来,但是在我的实际系统中,它是一个宽表,我想避免将所有数据拖入线路并将其放入内存的开销。

如果仅需要UserRolesId ,则可以执行以下查询:

 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}

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

更新资料

您可以尝试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; }
    }

除非您想控制多对多的表名和列名(这很简单),否则您就已经准备就绪。

创建用户

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();

关系应该已经存在:通常,如果您将双向的多对多关系定义为集合,则EF会为您生成联接表,这意味着您只需要聪明地设计LINQ查询即可:只是您可以看到的表格(有时会很棘手)。 (我从您的评论中认为“ EF似乎没有为您提供联接表”,确实是这种情况。)

因此,考虑到您给出的示例,结果将是这样的:

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

警告:如果没有找到具有Id==id或找到多个User (因此, Id不是密钥),将引发此警告。 但是,这通常正是您希望通过此类查询获得的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM