当前桥接类中的多迁移​​问题(多对多)

时间:2018-11-17 06:08:17

标签: c# asp.net-core .net-core asp.net-core-2.0

当前,我们有一个模型-HostApplicationUser,它桥接了 Host ApplicationUser (从IdentityUser扩展)之间的多对多关系。

public class HostApplicationUser
{
    public Guid HostID { get; set; }

    public Host Host { get; set; }

    public string Id { get; set; }

    public ApplicationUser ApplicationUser { get; set; }

    public bool IsDeleted { get; set; }

    [Timestamp]
    public byte[] RowVersion { get; set; }

}

在我们的ApplicationDBContext中,我们修改了受保护的重写void OnModelCreating(ModelBuilder builder),使其包括:

// Many to Many relationships

            builder.Entity<HostApplicationUser>()
                .HasKey(bc => new { bc.HostID, bc.Id });


            builder.Entity<HostApplicationUser>()
                .HasOne(bc => bc.Host)
                .WithMany(b => b.HostApplicationUsers)
                .HasForeignKey(bc => bc.HostID);

            builder.Entity<HostApplicationUser>()
                .HasOne(bc => bc.ApplicationUser)
                .WithMany(c => c.HostApplicationUsers)
                .HasForeignKey(bc => bc.Id);

此代码已正常运行。但是现在我们有一个新的要求,即添加一些属性/导航,如下所示:

public class HostApplicationUser
{
    public Guid HostID { get; set; }

    public Host Host { get; set; }

    public string Id { get; set; }

    public ApplicationUser ApplicationUser { get; set; }

    public DateTime CreatedUTC { get; set; }

    public string CreatedBy { get; set; }

    public DateTime LastModifiedUTC { get; set; }

    public string LastModifiedBy { get; set; }

    public DateTime? DeletedUTC { get; set; }

    public string DeletedBy { get; set; }

    public bool IsDeleted { get; set; }

    [Timestamp]
    public byte[] RowVersion { get; set; }

    [ForeignKey("CreatedBy")]
    public ApplicationUser ApplicationCreatedUser { get; set; }

    [ForeignKey("LastModifiedBy")]
    public ApplicationUser ApplicationLastModifiedUser { get; set; }

}

然后,当我们运行add-migration时出现错误:

  

无法确定类型为“ ApplicationUser”的导航属性“ HostApplicationUser.ApplicationCreatedUser”表示的关系。要么手动配置关系,要么使用“ [NotMapped]”属性或“ OnModelCreating”中的“ EntityTypeBuilder.Ignore”忽略此属性。

关于如何调整的任何想法可以解决此问题?我相信这与OnModelCreating(ModelBuilder builder)有关,以包括其他导航,但不确定如何做到这一点。

谢谢

1 个答案:

答案 0 :(得分:2)

原因

原因是从属实体和主体实体对具有多个导航属性。考虑HostApplicationUserApplicationUser之间的以下关系:

  1. ApplicationUser <-> HostApplicationUser.ApplicationUser
  2. ApplicationUser <-> HostApplicationUser.ApplicationCreatedUser
  3. ApplicationUser <-> HostApplicationUser.ApplicationLastModifiedUser
  4. ...和DeletedBy的潜在关系

如果您拥有HostApplicationUserApplicationUser的导航属性:

public class ApplicationUser{
    public string Id{get;set;}
    public string Name {get;set;}

    public IList<HostApplicationUser> HostApplicationUsers{get;set;} 
}

如果没有额外的配置,则EF Core无法确定Application.HostApplicationUsers属性是CreatedUsersLastModifiedUsersDeletedUsers还是其他用户,即, EF Core无法确定如何将ApplicationUser.HostApplicationUsers属性导航到HostApplicationUser ,因此抱怨:

  

无法确定类型为“ ApplicationUser”的导航属性“ HostApplicationUser.ApplicationCreatedUser”表示的关系。要么手动配置关系,要么使用“ [NotMapped]”属性或“ OnModelCreating”中的“ EntityTypeBuilder.Ignore”忽略此属性。

如何修复

要解决此问题,只需用 ApplicationUser.HostApplicationUsers 装饰InversePropertyAttribute

public class ApplicationUser{
    public string Id{get;set;}
    public string Name {get;set;}

    [InverseProperty("ApplicationUser")]
    public IList<HostApplicationUser> HostApplicationUsers{get;set;} 
}

或者,如果要具有多个导航属性,则需要为每个导航属性添加[InverseProperty("ApplicationCreatedUser")][InverseProperty("ApplicationLastModifiedUser")][InverseProperty("ApplicationDeletedUser")]等:

public class ApplicationUser{
    public string Id{get;set;}
    public string Name {get;set;}

    [InverseProperty("ApplicationUser")]
    public IList<HostApplicationUser> HostApplicationUsers{get;set;} 

    [InverseProperty("ApplicationCreatedUser")]
    public IList<HostApplicationUser> HostApplicationCreatedUsers{get;set;}

    [InverseProperty("ApplicationLastModifiedUser")]
    public IList<HostApplicationUser> HostApplicationLastModifiedUsers{get;set;}

    // ...
}