如何解决 Entity Framework 中数据库多对多映射的 Code First?
How to solve Code First from database many-to-many mapping in Entity Framework?
下面显示我的场景的代码片段:
[Table("User")]
public partial class UserModel
{
public UserModel()
{
UserRole = new HashSet<UserRoleModel>();
}
public int UserID { get; set; }
public string FullName { get; set; }
public virtual ICollection<UserRoleModel> UserRole { get; set; }
}
[Table("UserRole")]
public partial class UserRoleModel
{
public UserRoleModel()
{
User = new HashSet<UserModel>();
}
public int RoleID { get; set; }
public string RoleName { get; set; }
public virtual ICollection<UserModel> User { get; set; }
}
现在 OnModelCreating(DbModelBuilder modelBuilder)
EF 生成如下代码
modelBuilder.Entity<UserModel>()
.HasMany(e => e.UserRole)
.WithMany(e => e.User)
.Map(m => m.ToTable("UserRoleMapping").MapLeftKey("UserID").MapRightKey("UserRoleID"));
现在可以了添加/插入数据到UserRoleMapping
table。但是如何
Get / Update data from UserRoleMapping table ?
我尝试在 create-code-first-many-to-many 之后解决这个问题 post 并提出第三个 class 和 join entity
public partial class UserRoleMappingModel
{
[Key, Column(Order = 0)]
public Guid UserId { get; set; }
public UserModel User { get; set; }
[Key, Column(Order = 1)]
public int RoleId { get; set; }
public UserRoleModel UserRole { get; set; }
}
然后在 UserModel
和 UserRoleModel
中添加 public virtual ICollection<UserRoleMappingModel> UserRoleMapping { get; set; }
class
但是当我尝试使用下面的代码从数据库中获取值时
var results = _userRepository.GetAll()
.Include(r => r.UserRoleMapping
.Select(s => s.UserRole))
.SingleOrDefault(e => e.ID == id);
它抛出 错误
"An error occurred while executing the command definition. See the
inner exception for details.System.Data.SqlClient.SqlException
(0x80131904): Invalid object name 'dbo.UserRoleMappingModel'.\r\n
即使我在 OnModelCreating
中尝试了以下配置,但没有任何效果如预期的那样
modelBuilder.Entity<UserRoleMappingModel>()
.HasKey(e => new { e.UserId, e.RoleId });
您的 class UserRoleMappingModel
没有 Table-属性。因此,EF 搜索 Table UserRoleMappingModel
而不是 von UserRoleMapping
.
您必须选择:要么映射 n 对 n 关系并且不访问映射-table,要么加载 table 以访问其中的值。
作为解决方法,您可以实施未映射列:
[Table("User")]
public partial class UserModel
{
public UserModel()
{
UserRole = new HashSet<UserRoleModel>();
}
public int UserID { get; set; }
public string FullName { get; set; }
public virtual ICollection<UserRoleMappingModel> Mappings { get; set; }
public virtual ICollection<UserRoleModel> UserRole
{
get
{
return this.Mappings.Select(s => s.UserRole);
}
}
}
根据 GertArnold
的回复,我用下面的方式解决了这个问题。
1st 删除以下设置
modelBuilder.Entity<UserModel>()
.HasMany(e => e.UserRole)
.WithMany(e => e.User)
.Map(m => m.ToTable("UserRoleMapping").MapLeftKey("UserID").MapRightKey("UserRoleID"));
第二次添加波纹管设置
modelBuilder.Entity<UserRoleMappingModel>()
.HasKey(e => new { e.UserId, e.RoleId });
第三次在映射模型中添加table属性
[Table("UserRoleMapping")]
public partial class UserRoleMappingModel
{
[Key, Column(Order = 0)]
public Guid UserId { get; set; }
public UserModel User { get; set; }
[Key, Column(Order = 1)]
public int RoleId { get; set; }
public UserRoleModel UserRole { get; set; }
}
第 4 次创建映射存储库
IUserRoleMappingRepository
第5个简单的get方法(问题已解决)
var results = _userRoleMappingRepository.SearchFor(e => e.UserId == id)
.Select(s => new
{
s.UserId,
s.UserRoleId,
s.UserRole.RoleName
})
.FirstOrDefault();
注意点: 使用波纹管查询我能够得到结果但由于自引用问题
无法使用 Newtonsoft.Json
序列化
var results = _userRepository.GetAll()
.Include(r => r.UserRoleMapping
.Select(s => s.UserRole))
.SingleOrDefault(e => e.ID == id);
尝试以下 JsonSerializerSettingssetting
或者但无法成功序列化
PreserveReferencesHandling = PreserveReferencesHandling.All / Object
ReferenceLoopHandling = ReferenceLoopHandling.Serialize / Ignore
下面显示我的场景的代码片段:
[Table("User")]
public partial class UserModel
{
public UserModel()
{
UserRole = new HashSet<UserRoleModel>();
}
public int UserID { get; set; }
public string FullName { get; set; }
public virtual ICollection<UserRoleModel> UserRole { get; set; }
}
[Table("UserRole")]
public partial class UserRoleModel
{
public UserRoleModel()
{
User = new HashSet<UserModel>();
}
public int RoleID { get; set; }
public string RoleName { get; set; }
public virtual ICollection<UserModel> User { get; set; }
}
现在 OnModelCreating(DbModelBuilder modelBuilder)
EF 生成如下代码
modelBuilder.Entity<UserModel>()
.HasMany(e => e.UserRole)
.WithMany(e => e.User)
.Map(m => m.ToTable("UserRoleMapping").MapLeftKey("UserID").MapRightKey("UserRoleID"));
现在可以了添加/插入数据到UserRoleMapping
table。但是如何
Get / Update data from UserRoleMapping table ?
我尝试在 create-code-first-many-to-many 之后解决这个问题 post 并提出第三个 class 和 join entity
public partial class UserRoleMappingModel
{
[Key, Column(Order = 0)]
public Guid UserId { get; set; }
public UserModel User { get; set; }
[Key, Column(Order = 1)]
public int RoleId { get; set; }
public UserRoleModel UserRole { get; set; }
}
然后在 UserModel
和 UserRoleModel
中添加 public virtual ICollection<UserRoleMappingModel> UserRoleMapping { get; set; }
class
但是当我尝试使用下面的代码从数据库中获取值时
var results = _userRepository.GetAll()
.Include(r => r.UserRoleMapping
.Select(s => s.UserRole))
.SingleOrDefault(e => e.ID == id);
它抛出 错误
"An error occurred while executing the command definition. See the inner exception for details.System.Data.SqlClient.SqlException (0x80131904): Invalid object name 'dbo.UserRoleMappingModel'.\r\n
即使我在 OnModelCreating
中尝试了以下配置,但没有任何效果如预期的那样
modelBuilder.Entity<UserRoleMappingModel>()
.HasKey(e => new { e.UserId, e.RoleId });
您的 class UserRoleMappingModel
没有 Table-属性。因此,EF 搜索 Table UserRoleMappingModel
而不是 von UserRoleMapping
.
您必须选择:要么映射 n 对 n 关系并且不访问映射-table,要么加载 table 以访问其中的值。
作为解决方法,您可以实施未映射列:
[Table("User")]
public partial class UserModel
{
public UserModel()
{
UserRole = new HashSet<UserRoleModel>();
}
public int UserID { get; set; }
public string FullName { get; set; }
public virtual ICollection<UserRoleMappingModel> Mappings { get; set; }
public virtual ICollection<UserRoleModel> UserRole
{
get
{
return this.Mappings.Select(s => s.UserRole);
}
}
}
根据 GertArnold
的回复,我用下面的方式解决了这个问题。
1st 删除以下设置
modelBuilder.Entity<UserModel>()
.HasMany(e => e.UserRole)
.WithMany(e => e.User)
.Map(m => m.ToTable("UserRoleMapping").MapLeftKey("UserID").MapRightKey("UserRoleID"));
第二次添加波纹管设置
modelBuilder.Entity<UserRoleMappingModel>()
.HasKey(e => new { e.UserId, e.RoleId });
第三次在映射模型中添加table属性
[Table("UserRoleMapping")]
public partial class UserRoleMappingModel
{
[Key, Column(Order = 0)]
public Guid UserId { get; set; }
public UserModel User { get; set; }
[Key, Column(Order = 1)]
public int RoleId { get; set; }
public UserRoleModel UserRole { get; set; }
}
第 4 次创建映射存储库
IUserRoleMappingRepository
第5个简单的get方法(问题已解决)
var results = _userRoleMappingRepository.SearchFor(e => e.UserId == id)
.Select(s => new
{
s.UserId,
s.UserRoleId,
s.UserRole.RoleName
})
.FirstOrDefault();
注意点: 使用波纹管查询我能够得到结果但由于自引用问题
无法使用Newtonsoft.Json
序列化
var results = _userRepository.GetAll()
.Include(r => r.UserRoleMapping
.Select(s => s.UserRole))
.SingleOrDefault(e => e.ID == id);
尝试以下 JsonSerializerSettingssetting
或者但无法成功序列化
PreserveReferencesHandling = PreserveReferencesHandling.All / Object
ReferenceLoopHandling = ReferenceLoopHandling.Serialize / Ignore