0

下面的代码片段显示了我的场景:

[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到表中。但是如何

从 UserRoleMapping 表中获取/更新数据?

我尝试在create-code-first-many-to-many帖子之后解决这个问题,并提出第三类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; }
    }

然后添加public virtual ICollection<UserRoleMappingModel> UserRoleMapping { get; set; }UserModelUserRoleModel

但是当我尝试使用下面的代码从数据库中获取值时

var results = _userRepository.GetAll()
                 .Include(r => r.UserRoleMapping
                 .Select(s => s.UserRole))
                 .SingleOrDefault(e => e.ID == id); 

它抛出错误

"执行命令定义时出错。有关详细信息,请参阅内部异常。System.Data.SqlClient.SqlException (0x80131904): 对象名称 'dbo.UserRoleMappingModel' 无效。\r\n

即使我尝试了以下配置OnModelCreating,但没有按预期工作

modelBuilder.Entity<UserRoleMappingModel>()
 .HasKey(e => new { e.UserId, e.RoleId });
4

2 回答 2

0

您的班级UserRoleMappingModel没有表属性。因此,EF 搜索 TableUserRoleMappingModel而不是 von UserRoleMapping

您必须选择:映射 n 对 n 关系并且不访问映射表或加载表以访问其中的值。

作为解决方法,您可以实现一个未映射的列:

[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);
        }
    }
}
于 2018-01-11T10:24:42.237 回答
0

根据GertArnold回复,我通过以下方式解决了这个问题。

第一次删除以下设置

modelBuilder.Entity<UserModel>()
                .HasMany(e => e.UserRole)
                .WithMany(e => e.User)
                .Map(m => m.ToTable("UserRoleMapping").MapLeftKey("UserID").MapRightKey("UserRoleID"));

2添加波纹管设置

modelBuilder.Entity<UserRoleMappingModel>()
 .HasKey(e => new { e.UserId, e.RoleId });

第三次在映射模型中添加表属性

[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
于 2018-01-11T19:39:24.127 回答