实体框架 - 将表拆分为具有重叠条件的多个实体

Posted

技术标签:

【中文标题】实体框架 - 将表拆分为具有重叠条件的多个实体【英文标题】:Entity Framework - Splitting table to multiple entities WITH AN OVERLAPPING CONDITION 【发布时间】:2011-04-27 19:17:56 【问题描述】:

有没有办法执行以下映射(使用数据库优先方法)

表:(仅出于可读性目的使用类似 C# 的语法定义表)

table MainItems

    column PK not-null unique int MainItemKey;
    column string Name;
    column string AspectAInfo;
    column string AspectBInfo;

    // 0 for A, 1 for B, 2 for both (Could be replaced with 2 boolean columns)
    column not-null int AspectABOrBoth;


table AspectAMoreInfo

    column PK not-null unique in AspectAMoreInfoKey;
    column FK not-null int MainItemKey;
    column string PayLoadA;


table AspectBMoreInfo

    column PK not-null unique in AspectBMoreInfoKey;
    column FK not-null int MainItemKey;
    column double PayLoadB;

实体:

// Map to MainItems table if column AspectABOrBoth is 0 or 2
class TypeAItem

    // Map to MainItemKey column
    int TypeAItemKey  get; set; 

    string Name  get; set;  // Map to Name column

    // Navigation property to AspectAMoreInfo rows
    List<TypeAMoreInfo> MoreInfo  get; set; 

    // Navigation property to MainItems row when AspectABOrBoth is 2
    TypeBItem OptionalInnerItemB  get; set; 


// Map to MainItems table if column AspectABOrBoth is 1 or 2
class TypeBItem

    // Map to MainItemKey column
    int TypeBItemKey  get; set; 

    string Name  get; set;  // Map to Name column

    // Navigation property to AspectBMoreInfo rows
    List<TypeBMoreInfo> MoreInfo  get; set; 


// Map to AspectAMoreInfo table
class TypeAMoreInfo

    // Map to AspectAMoreInfoKey column
    int TypeAMoreInfoKey  get; set; 

    // Navigation property to MainItems row when MainItems.AspectABOrBoth is 0 or 2
    TypeAItem Owner  get; set; 


// Map to AspectBMoreInfo table
class TypeBMoreInfo

    // Map to AspectBMoreInfoKey column
    int TypeBMoreInfoKey  get; set; 

    // Navigation property to MainItems row when MainItems.AspectABOrBoth is 1 or 2
    TypeBItem Owner  get; set; 

我考虑过但不想采取的可能方向包括:

    在 MainItems 表上方定义 2 个视图并将实体映射到它们。 (可以将基类型与此一起使用,与 Table-Per-Concrete-Type 一起使用。)

    向 MainItems 表添加 2 个可为空的 FK 列,指向自身(指向同一行)而不是 AspectABOrBoth 列 (如果 MainItem 是 AspectA,则 1 个非空,如果 MainItem 是 AspectB,则另一个非空。) (可以根据新的 FK 列使用表拆分。)

【问题讨论】:

【参考方案1】:

使用时可以将表拆分为多个实体:

Table splitting - 它要求实体只共享密钥,并且每个其他属性只能映射到单个实体。 TPH inheritance - 它要求基础实体定义键和共享属性。子实体可以包含其他属性,但属性不能在子实体之间共享。表必须包含一个或多个特殊列(区分符),这些列将定义记录代表的继承层次结构中的类型。 MSL 不允许 discriminator 使用任何复杂的表达式。复杂条件只能创建为所有条件的逻辑与。

如果我查看您的表格,它看起来不像继承。 TableAItemTableBItem 没有任何共享属性。唯一的共享项可能是关键,这会使您的设计的其余部分变得非常困难,因为与TableAMoreInfoTableBMoreInfo 的关系将使用MainItem(密钥持有者)而不是子项创建。

视图看起来更适合解决此问题,但视图在 EF 中默认为只读,除非您手动修改 SSDL。

【讨论】:

可以有共享属性,比如我刚刚添加到示例中的“名称”。 TPH 继承会很好,除了一行不能同时映射到两个不同的派生类型。不能使用条件拆分表,至少不能通过设计器。 这更多的是关于“让我们尝试一下,你会看到”。这不是一件容易的事。并非所有内容都可以根据需要使用 EF 进行映射。 我是这么认为的,在不破坏现有用法的情况下将新模型映射到现有模式可能具有挑战性。

以上是关于实体框架 - 将表拆分为具有重叠条件的多个实体的主要内容,如果未能解决你的问题,请参考以下文章

Fluent NHibernate 为重叠实体创建实体映射

实体框架 - 具有多个条件的异步选择

具有多个连接条件的实体框架查询

当来自不同实体类型的 ID 重叠时,是不是可以将 @JsonIdentityInfo 与 ObjectIdGenerators.PropertyGenerator 一起使用?

在实体框架中加载具有过滤条件的子对象记录

Flutter 使用 Stack 或任何其他方法重叠具有动态高度的多个小部件