EF Core: inherited entities has navs to same table

c# entity-framework entity-framework-core

Question

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

There is error:

The foreign keys {NavID} on 'ConcreteSecond' and {'NavID'} on 'ConcreteFirst' are both mapped to FK_Bases_Navigations_NavID' but with different uniqueness

I guess it can be fixed of renaming either ConcreteFirst.Nav or ConcreteSecond.Nav property but it will cause of the increase of columns in Bases table. How can I resolve this issue with Nav name for both ConcreteFirst and ConcreteSecond?

1
0
6/29/2017 12:33:23 PM

Popular Answer

Entity Framework supports different inheritance strategies.

Table Per Hierarchy is the default one. So, by default, EF uses single table for both parent and it's children.

You can easely change this behavior. Just specify the table you wish to use:

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

If you would like to not even use a separate table for parent's properties, just don't register it and map these properties to the children tables like this:

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

================

UPD:

EF Core behavior is a bit different. It, if you use ToTable method, will map all of the parent properties by default.

0
6/29/2017 12:34:16 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow