EF Core:继承的实体已导航到同一个表 [英] EF Core: inherited entities has navs to same table

查看:805
本文介绍了EF Core:继承的实体已导航到同一个表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public $ class $ {pre> 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;组; }
public ICollection< ConcreteFirst> ConcreteFirsts {get; set; }
public ICollection< ConcreteSecond> ConcreteSeconds {get; set;
}

// OnModelCreating
builder.Entity< Base>()忽略(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>基地{get; set;}
DbSet< ConcreteFirst>首先{get; set;}
DbSet< ConcreteSecond>秒set;}
DbSet< Navigation>导航{get;组;

有错误:



'ConcreteFirst'上的ConcreteSecond和NavID}上的外键{NavID}都映射到FK_Bases_Navigations_NavID'但
具有不同的唯一性


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

解决方案

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



是默认的。因此,默认情况下,EF为父代和父母使用单表。



您可以轻松地改变这种行为。只需指定要使用的表:

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

如果您不想使用单独的表格父属的属性,只是不注册它,并将这些属性映射到这些子表中:

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

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



UPD:



EF核心行为有所不同。
如果您使用ToTable方法,将默认映射所有父属性。


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?

解决方案

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.

这篇关于EF Core:继承的实体已导航到同一个表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆