实体框架代码优先和原始类型的集合

Eri*_* J. 10 entity-framework ef-code-first entity-framework-4.1

当创建包含基本类型集合并由EF Code First持久化的POCO类时,到目前为止我发现的最好建议是创建一个具有ID加上基本类型的新类:

具有简单数组的实体框架和模型

如果我现在有需要类型的属性几类ObservableCollection<string>,并取代它们ObservableCollection<EntityString>(这里EntityString是一个ID和一个字符串属性自定义类型),我结束了一个表EntityString有多个外键列,一个类型的每个属性ObservableCollection<EntityString>跨越所有具有此类属性的具体类型.

这导致表中大多数为空的外键列膨胀EntityString.

一种方法是创建子类,EntityString并为这些子类使用Table per Type模型.但是,这需要对对象模型进行笨拙的更改,以适应实体框架.

问题:

  • 封装类型是最好的管理方式Collection<PrimitiveType>吗?
  • 如果是这样,那么允许多个(多个)外键列与每种类型创建自定义表(以笨拙的模型为代价)的专业和概念是什么?

Lad*_*nka 5

将简单类型提升为实体是一种选择.如果要在更多关系中使用新的基本类型实体,最好从该实体中完全删除导航属性并使用独立关联(无FK属性).

public class StringEntity
{
    public int Id { get; set; }
    public string Text { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和映射:

modelBuilder.Entity<Foo1>().HasMany(f => f.Strings).WithOptional();
modelBuilder.Entity<Foo2>().HasMany(f => f.Strings).WithOptional();
Run Code Online (Sandbox Code Playgroud)

在数据库中,您将获得每个相关主体的新可空FK - 除了为StringEntity每个主体创建特殊类之外没有办法避免它(不要因为它影响性能而使用继承).

还有另一种选择:

public class StringEntity
{
    public int Id { get; set; }
    public List<string> Strings { get; private set; }

    public string Text 
    {
        get
        {
            return String.Join(";", Strings);
        }

        set
        {
            Strings = value.Split(";").ToList();
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您不需要相关的实体类型(和附加表),但您的实体受到其他属性的污染,Text该属性仅用于持久性.