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);
需要注意的是,如果没有 User
与 Id==id
一起找到,或者如果找到多个(因此 Id
不是键),这将抛出。然而,这通常正是您想要的此类查找。
我需要在 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);
需要注意的是,如果没有 User
与 Id==id
一起找到,或者如果找到多个(因此 Id
不是键),这将抛出。然而,这通常正是您想要的此类查找。