Entity Framework 太多太多未填充结果
Entity Framework Many-Too-Many Not Populating Results
我正在尝试使用代码优先迁移在 C# EF 中映射一个太多太多的关系。
我遇到的问题是没有从相关 table 填充任何结果。以这段代码为例,_role
不包含任何权限,而它应该包含 4 个结果:
foreach (Role _role in _dbContext.Roles) //_dbContext.Roles.Count = 2
{
foreach(Permission _permission in _role.Permissions) //_role.Permissions.Count = 0
{
//Do something with each _permission
}
}
类 看起来像这样:
[Table("Roles")]
public partial class Role
{
public Role()
{
Permissions = new HashSet<Permission>();
}
[Key]
public int RoleId { get; set; }
public string RoleName { get; set; }
public ICollection<Permission> Permissions { get; set; }
}
[Table("Permissions")]
public partial class Permission
{
public Permission()
{
Roles = new HashSet<Role>();
}
[Key]
public int PermissionId { get; set; }
public string PermissionName { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
最后是 Fluent API:
modelBuilder.Entity<Permission>()
.HasMany(e => e.Roles)
.WithMany(e => e.Permissions)
.Map(m => m
.ToTable("_Lnk_Role_Permission")
.MapLeftKey("PermissionId")
.MapRightKey("RoleId"));
检查数据库后,tables、键和数据都按顺序排列,手动添加和查询数据会产生正确的结果。尝试访问数据时,存在角色但没有权限。
谁能看出哪里出了问题?
好吧,经过几个小时的挠头,我错过了 ICollection
的 Virtual
。修改后的 class 看起来像这样:
public partial class Role
{
public Role()
{
Permissions = new HashSet<Permission>();
}
[Key]
public int RoleId { get; set; }
public string RoleName { get; set; }
public Virtual ICollection<Permission> Permissions { get; set; } //Notice the virtual?!
}
我认为您正在寻找 Include 语句。
foreach (var role in _dbContext.Roles.Include(x => x.Permissions))
{
...
}
virtual 关键字是一种很好的做法,它在数据加载方式中发挥着重要作用。如果您不小心,最终可能会进行 1+N 次查询(1 次用于 Role 对象 + N 次用于每个 Permission)。 Include 语句告诉 EF 有效地连接数据库查询中的表,以便内存中的数据可用于处理嵌套的 for 循环。
很抱歉链接到别处,但 MSDN 链接应该暂时在这里。这是一本很好的读物,可以理解 virtual/non-virtual 和 with/without Include 语句的含义:
https://msdn.microsoft.com/en-us/data/jj574232.aspx
我正在尝试使用代码优先迁移在 C# EF 中映射一个太多太多的关系。
我遇到的问题是没有从相关 table 填充任何结果。以这段代码为例,_role
不包含任何权限,而它应该包含 4 个结果:
foreach (Role _role in _dbContext.Roles) //_dbContext.Roles.Count = 2
{
foreach(Permission _permission in _role.Permissions) //_role.Permissions.Count = 0
{
//Do something with each _permission
}
}
类 看起来像这样:
[Table("Roles")]
public partial class Role
{
public Role()
{
Permissions = new HashSet<Permission>();
}
[Key]
public int RoleId { get; set; }
public string RoleName { get; set; }
public ICollection<Permission> Permissions { get; set; }
}
[Table("Permissions")]
public partial class Permission
{
public Permission()
{
Roles = new HashSet<Role>();
}
[Key]
public int PermissionId { get; set; }
public string PermissionName { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
最后是 Fluent API:
modelBuilder.Entity<Permission>()
.HasMany(e => e.Roles)
.WithMany(e => e.Permissions)
.Map(m => m
.ToTable("_Lnk_Role_Permission")
.MapLeftKey("PermissionId")
.MapRightKey("RoleId"));
检查数据库后,tables、键和数据都按顺序排列,手动添加和查询数据会产生正确的结果。尝试访问数据时,存在角色但没有权限。
谁能看出哪里出了问题?
好吧,经过几个小时的挠头,我错过了 ICollection
的 Virtual
。修改后的 class 看起来像这样:
public partial class Role
{
public Role()
{
Permissions = new HashSet<Permission>();
}
[Key]
public int RoleId { get; set; }
public string RoleName { get; set; }
public Virtual ICollection<Permission> Permissions { get; set; } //Notice the virtual?!
}
我认为您正在寻找 Include 语句。
foreach (var role in _dbContext.Roles.Include(x => x.Permissions))
{
...
}
virtual 关键字是一种很好的做法,它在数据加载方式中发挥着重要作用。如果您不小心,最终可能会进行 1+N 次查询(1 次用于 Role 对象 + N 次用于每个 Permission)。 Include 语句告诉 EF 有效地连接数据库查询中的表,以便内存中的数据可用于处理嵌套的 for 循环。
很抱歉链接到别处,但 MSDN 链接应该暂时在这里。这是一本很好的读物,可以理解 virtual/non-virtual 和 with/without Include 语句的含义: https://msdn.microsoft.com/en-us/data/jj574232.aspx