实体框架6.1:派生类型和识别关系中的1-1和1-多关系

时间:2014-09-03 14:56:52

标签: c# entity-framework entity-framework-6.1 ef-fluent-api

更新:我应该注意到Id上的NavigationPropertyClass属性不是数据库生成的。在我的实际模型中,NavigationPropertyClass也是层次结构方案的一部分(使用TPH),此处未显示,而NavigationPropertyClass具有DerivedClass1实例和{{1}的集合对于从DerivedClass2派生的基类继承的所有类,情况不一定如此。


我的模型的一部分看起来像这样(为简洁省略了其他属性和构造函数):

NavigationPropertyClass

//Many other classes inherit from this class //and many of the derived classes are not composed of DerivedClass1 or DerivedClass2 public abstract SomeOtherBaseClass{ public int Id {get; set;} //not database generated, set in the constructor } public NavigationPropertyClass: SomeOtherBaseClass{ public DerivedClass1 Derived1 {get; set;} public virtual ICollection<DerivedClass2> Derived2Collection {get; set;} } public abstract class BaseClass{ public int Id {get; set;} //other properties shared by derived classes } public class DerivedClass1: BaseClass{ public NavigationPropertyClass NavigationProperty {get; set;} //other properties pertinent to DerivedClass1 } public class DerivedClass2: BaseClass{ public NavigationPropertyClass NavigationProperty {get; set;} //other properties pertinent to DerivedClass2 } DerivedClass1有1-1关系,而NavigationPropertyClassDerivedClass2有多个关系。

我尝试在每个派生类中设置标识关系,以便在从数据库中删除NavigationPropertyClass的实例时,NavigationPropertyClassDerivedClass1的关联实例也是如此DerivedClass2的任何实例。我可以看到设置它的唯一方法是使用TPT继承,但即便如此,我也无法正常工作。我发布了我的Fluent API配置,但是我已经尝试了很多这样的排列,我不知道要发布哪一个。

有没有办法做我想做的事情?如果是这样,Fluent API配置是什么样的?

1 个答案:

答案 0 :(得分:0)

这是符合您要求的型号。

public abstract class Base
{
    public int Id { get; set; }
}
public class Derived1 : Base
{
    public int PropDerived1 { get; set; }
    public NavigationPropertyClass NavigationProperty { get; set; }
}
public class Derived2 : Base
{
    public int PropDerived2 { get; set; }

    public int NavigationPropertyClassId { get; set; }
    public NavigationPropertyClass NavigationPropertyClass { get; set; }
}
public abstract class SomeOtherBaseClass
{
    public int Id { get; set; }
}
public class NavigationPropertyClass : SomeOtherBaseClass
{
    public Derived1 Derived1 { get; set; }
    public virtual ICollection<Derived2> Derived2s { get; set; }
}

在配置模型构建器时,您只需要使用ToTable来获得TPT继承。

public class AppContext : DbContext
{
    public DbSet<SomeOtherBaseClass> SomeOtherBaseClasses { get; set; }
    public DbSet<Base> Bases { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Derived1>().ToTable("Derived1");
        modelBuilder.Entity<Derived2>().ToTable("Derived2");
        modelBuilder.Entity<NavigationPropertyClass>().ToTable("NavigationPropertyClass");

        modelBuilder.Entity<NavigationPropertyClass>()
            .HasRequired(x => x.Derived1)
            .WithRequiredDependent(x => x.NavigationProperty);
    }
}

并将所有内容保留至EF convention,但NavigationPropertyClass::Id也是Derived1的FK的部分除外。

结果

Result

NavigationPropertyClass表上简化生成的约束:

PRIMARY KEY [Id]
FOREIGN KEY([Id]) REFERENCES [dbo].[Derived1] ([Id])
FOREIGN KEY([Id]) REFERENCES [dbo].[SomeOtherBaseClasses] ([Id])

更多