【问题标题】:Entity framework 6.1: 1-1 and 1-many relationship in derived types and identifying relationships实体框架 6.1:派生类型和识别关系中的 1-1 和 1-many 关系
【发布时间】:2014-09-03 14:56:52
【问题描述】:

更新:我应该注意到NavigationPropertyClass 上的Id 属性不是数据库生成的。在我的实际模型中,NavigationPropertyClass 也是层次结构方案(使用 TPH)的一部分,此处未显示,而NavigationPropertyClass 有一个DerivedClass1 实例和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
}

DerivedClass1NavigationPropertyClass 是一对一关系,而DerivedClass2NavigationPropertyClass 是多对一关系。

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

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

【问题讨论】:

  • 虽然 Derived2 与 NavigationPropertyClass 有一对多的关系 => 一个 Derived2 有多个 NavigationPropertyClass ?
  • @YuliamChandra 已编辑以正确识别关系的方向。
  • EF 不必知道Base,可以将派生类映射为独立实体。

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


【解决方案1】:

这是符合您要求的型号。

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 的部分。

结果

NavigationPropertyClass 表上的简化生成约束:

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

更多

【讨论】:

  • 看起来我可能过度简化了我的模型,因为 NavigationPropertyClass 上的 Id 不是标识列,因此 NavigationPropertyClass 是关系的主要端。我会相应地更新我的问题。
  • @joelmdev,我根据您更新的问题更新了答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多