首页 文章

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

提问于
浏览
1

目前,我们有这个模型 - HostApplicationUser,它为 HostApplicationUser (从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构建器),包括如下:

// 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(模型构建器构建器)有关,包括其他导航但不知道如何做到这一点 .

谢谢

1 回答

  • 2

    原因

    原因是 there're multiple navigation properties on the dependent and principal entities pairs . 考虑 HostApplicationUserApplicationUser 之间的以下关系:

    • ApplicationUser <-> HostApplicationUser.ApplicationUser

    • ApplicationUser <-> HostApplicationUser.ApplicationCreatedUser

    • ApplicationUser <-> HostApplicationUser.ApplicationLastModifiedUser

    • ......和 DeletedBy 的潜在关系

    如果您在 ApplicationUser 上有 HostApplicationUser 的导航属性:

    public class ApplicationUser{
        public string Id{get;set;}
        public string Name {get;set;}
    
        public IList<HostApplicationUser> HostApplicationUsers{get;set;} 
    }
    

    如果没有额外的配置, EF Core 无法确定 Application.HostApplicationUsers 属性是 CreatedUsersLastModifiedUsersDeletedUsers 或其他用户,即 the EF Core cannot determine how the ApplicationUser.HostApplicationUsers property is navigated to HostApplicationUser ,因此抱怨:

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

    如何修复

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

    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;}
    
        // ...
    }
    

相关问题