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

时间:2011-04-27 19:17:56

标签: entity-framework orm entity-framework-4 database-schema mapping-model

有没有办法预先形成以下映射(使用数据库优先方法)

表:(为了可读性目的,使用类似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; }
}

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

  1. 在MainItems表上定义2个视图并将实体映射到它们 (可以使用带有此类型的基本类型以及Table-Per-Concrete-Type。)

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

1 个答案:

答案 0 :(得分:0)

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

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

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

视图看起来更适合解决此问题,但除非您手动修改SSDL,否则默认情况下只能在EF中查看。