EF Core:继承的实体具有导航到同一个表

时间:2017-06-29 11:53:47

标签: c# entity-framework entity-framework-core

public abstract class Base {
    public Guid Id { get;set; }
    public Navigation Nav { get;set; }
    public string NavID { get;set; }
}

public class ConcreteFirst: Base { }

public class ConcreteSecond: Base { }

public class Navigation Nav {
    public string NavID { get; set; }
    public ICollection<ConcreteFirst> ConcreteFirsts { get;set; }
    public ICollection<ConcreteSecond> ConcreteSeconds { get;set; }
}

//OnModelCreating
builder.Entity<Base>().Ignore(b => b.Nav);

builder.Entity<ConcreteFirst>()
       .HasOne(c => c.Nav)
       .WithMany(n => n.ConcreteFirsts)
       .HasForeignKey(c => c.NavID);

builder.Entity<ConcreteSecond>()
       .HasOne(c => c.Nav)
       .WithMany(n => n.ConcreteSeconds)
       .HasForeignKey(c => c.NavID);
//...
DbSet<Base> Bases { get; set;}
DbSet<ConcreteFirst> Firsts { get; set;}
DbSet<ConcreteSecond> Seconds { get; set;}
DbSet<Navigation> Navigations { get; set; }

有错误:

  

&#39; ConcreteSecond&#39;上的外键{NavID}和{&#39; NavID&#39;}   &#39; ConcreteFirst&#39;都被映射到FK_Bases_Navigations_NavID&#39;但   具有不同的独特性

我想可以修复ConcreteFirst.Nav或ConcreteSecond.Nav属性的重命名,但它会导致Bases表中列的增加。如何使用ConcreteFirst和ConcreteSecond的Nav名称解决此问题?

1 个答案:

答案 0 :(得分:0)

实体框架支持不同的继承策略。

每个层次结构表是默认值。因此,默认情况下,EF对父级及其子级使用单个表。

您可以轻松更改此行为。只需指定您要使用的表格:

builder.Entity<ConcreteFirst>()
    .ToTable("Firsts");
// ...
builder.Entity<ConcreteSecond>()
    .ToTable("Seconds");
// ...

如果您不想为父的属性使用单独的表,只需不要注册它并将这些属性映射到子表,如下所示:

builder.Entity<ConcreteFirst>().Map(m => {
    m.MapInheritedProperties();
    m.ToTable("Firsts");
    // ...
});
// ...

=====

UPD:

EF Core的行为有点不同。 如果使用ToTable方法,它将默认映射所有父属性。