Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF 5具有多层继承的混合继承类型_C#_Entity Framework_Hierarchy - Fatal编程技术网

C# EF 5具有多层继承的混合继承类型

C# EF 5具有多层继承的混合继承类型,c#,entity-framework,hierarchy,C#,Entity Framework,Hierarchy,我在使用实体框架将现有数据库映射到代码库时遇到问题。我似乎也找不到任何做过类似事情的代码。我需要有多层继承,我需要层使用两种不同的映射类型。不过我有一些奇怪的行为。为了重现这种行为,我创建了一个简单的模型,并允许EF按照它希望的方式进行映射 我的实体如下: public abstract class Root { public int RootId { get; set; } public string RootProperty { get; set; } } public

我在使用实体框架将现有数据库映射到代码库时遇到问题。我似乎也找不到任何做过类似事情的代码。我需要有多层继承,我需要层使用两种不同的映射类型。不过我有一些奇怪的行为。为了重现这种行为,我创建了一个简单的模型,并允许EF按照它希望的方式进行映射

我的实体如下:

public abstract class Root
{
    public int RootId { get; set; }

    public string RootProperty { get; set; }
}

public abstract class ChildA : Root
{
    public string ChildAProperty { get; set; }
}

public class ChildB : Root
{
    public string ChildBProperty { get; set; }
}

public class SubChildAa : ChildA
{
    public string SubChildAaProperty { get; set; }
}

public class SubChildAb : ChildA
{
    public string SubChildAbProperty { get; set; }
}
class MyContext : DbContext
{
    public DbSet<SubChildAa> ChildAas { get; set; }
    public DbSet<SubChildAb> ChildAbs { get; set; }
    public DbSet<ChildB> ChildBs { get; set; }

    public MyContext()
    {
        //Database.SetInitializer<MyContext>(null);
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<Root>().ToTable("Root");

        modelBuilder.Entity<ChildB>().ToTable("ChildB");

        modelBuilder.Entity<ChildA>().ToTable("ChildA");
        modelBuilder.Entity<ChildA>().Map<SubChildAa>(u => u.Requires("ChildAType").HasValue("SubChildAa"));
        modelBuilder.Entity<ChildA>().Map<SubChildAb>(u => u.Requires("ChildAType").HasValue("SubChildAb"));
        //base.OnModelCreating(modelBuilder);
    }


}
这将导致以下模式:

我的背景如下:

public abstract class Root
{
    public int RootId { get; set; }

    public string RootProperty { get; set; }
}

public abstract class ChildA : Root
{
    public string ChildAProperty { get; set; }
}

public class ChildB : Root
{
    public string ChildBProperty { get; set; }
}

public class SubChildAa : ChildA
{
    public string SubChildAaProperty { get; set; }
}

public class SubChildAb : ChildA
{
    public string SubChildAbProperty { get; set; }
}
class MyContext : DbContext
{
    public DbSet<SubChildAa> ChildAas { get; set; }
    public DbSet<SubChildAb> ChildAbs { get; set; }
    public DbSet<ChildB> ChildBs { get; set; }

    public MyContext()
    {
        //Database.SetInitializer<MyContext>(null);
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<Root>().ToTable("Root");

        modelBuilder.Entity<ChildB>().ToTable("ChildB");

        modelBuilder.Entity<ChildA>().ToTable("ChildA");
        modelBuilder.Entity<ChildA>().Map<SubChildAa>(u => u.Requires("ChildAType").HasValue("SubChildAa"));
        modelBuilder.Entity<ChildA>().Map<SubChildAb>(u => u.Requires("ChildAType").HasValue("SubChildAb"));
        //base.OnModelCreating(modelBuilder);
    }


}
class MyContext:DbContext
{
公共DbSet ChildAas{get;set;}
公共DbSet ChildAbs{get;set;}
公共DbSet ChildBs{get;set;}
公共MyContext()
{
//Database.SetInitializer(null);
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().ToTable(“根”);
modelBuilder.Entity().ToTable(“ChildB”);
modelBuilder.Entity().ToTable(“ChildA”);
modelBuilder.Entity().Map(u=>u.Requires(“ChildAType”).HasValue(“SubChildAa”);
modelBuilder.Entity().Map(u=>u.Requires(“ChildAType”).HasValue(“SubChildAb”);
//基于模型创建(modelBuilder);
}
}
我正在尝试将TPT用于根到子(A或B)映射,将TPH用于子到子的映射。主要问题是EF将鉴别器放在根对象上。它还将ChildA属性放在那里,我认为这是不正确的,但目前问题不大。当鉴别器位于根上时,会导致错误,因为ChildB未映射到该鉴别器中的类型

有没有人能建议一种方法,让ChildA表实际维护自己的属性和鉴别器,而不将它们推到根表

像这样的

public abstract class Root
{
  [Key]
  public int RootId { get; set; }
  public string RootProperty { get; set; }
}

public class ChildA : Root
{
 [Required]
 int RootId 
 ForeignKey["RootId"]
 public Root Root {get;set;}    
 public string ChildAProperty { get; set; }
} 

public class ChildB : Root {
   [Required]
   int RootId   
   ForeignKey["RootId"]
   public Root Root {get;set;}      
   public string ChildBProperty { get; set; }
 }

public class SubChildAa : ChildA
{
  public string SubChildAaProperty { get; set; }
}

public class SubChildAb : ChildA
{
  public string SubChildAbProperty { get; set; }
}
在您的上下文中,您希望ChildA和ChildB使用TPT

所以

public DbSet ChildAas{get;set;}
公共DbSet ChildBs{get;set;}
儿童TPH

  public DbSet<SubChild> Childs { get; set; }
public DbSet Childs{get;set;}

为什么要从Root继承并在ChildA和B中公开Root类型的属性?我假设从DbSet你是指我定义的两个类型中的任何一个,而不是一个新类型?我并不是真的在寻找一个“类似的东西”。我了解如何独立绘制TPT和TPH。问题是如何将它们结合起来。我实现了代码,它确实产生了我想要的模式,但存在一些问题。没有创建鉴别器,这很容易通过在上下文中重载ModelCreating并指定鉴别器来解决。更大的问题是它对该领域模型的模糊性。我可以先创建一个ChildA,然后创建一个ChildB,然后将ChildA的根设置为ChildB,它就会爆炸(这是意料之中的)。这确实解决了在ChildA表上具有ChildA属性和鉴别器的问题,但就代码而言,这是一个很大的设计折衷。但是,导航属性也需要与外键关联,该位在ChildA和ChildB类中完成,这就是根属性重复的原因