2011-11-30 71 views
8

当创建包含原始类型集合并由EF Code First持久化的POCO类时,目前为止我发现的最佳建议是创建一个具有ID和ID的新类基本类型:实体框架代码第一个和原始类型的集合

Entity Framework and Models with Simple Arrays

如果我现在有需要ObservableCollection<string>类型的属性,并与ObservableCollection<EntityString>(其中EntityString是一个ID和一个字符串属性自定义类型),我结束了一个替换它们几类表EntityString具有多个外键列,每个属性类型为跨所有具有此类特性的混凝土类型的。

这会导致EntityString表中大部分为空的外键列膨胀。

一种方法是创建EntityString的子类,并使用Table per Type模型用于这些子类。但是,这需要对对象模型进行尴尬的改变,以适应实体框架。

问题:

  • 是封装型管理Collection<PrimitiveType>的最佳方式?
  • 如果是这样,那么允许多个(许多)外键列与每个类型创建自定义表格(以一个尴尬模型为代价)的pro和con函数是什么?

回答

5

将简单类型提升为实体是一种选择。如果你想在更多的关系中使用这个新的基元类型实体,最好从该实体中完全移除导航属性并使用独立的关联(没有FK属性)。

public class StringEntity 
{ 
    public int Id { get; set; } 
    public string Text { get; set; } 
} 

和映射:

modelBuilder.Entity<Foo1>().HasMany(f => f.Strings).WithOptional(); 
modelBuilder.Entity<Foo2>().HasMany(f => f.Strings).WithOptional(); 

在数据库中,你会得到每相关负责新可空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(); 
     } 
    } 
} 

在这种情况下,你不需要相关的实体类型(和附加表),但你的实体污染与附加属性Text这是唯一的持久性。

+1

该解决方案假定';' (或任何其他魔法字符被选中)对于基本字符串而言是无效的输入,是正确的? –

+0

是否可以使用类属性来表示流畅配置'WithOptional'?我知道它们是彼此的替代品,但迄今为止尚未找到有关此主题的完整文档。 –

+0

如果默认映射不会使关系成为可选项,则不能使用数据注释对其进行更改。数据注释必须放置在某个属性上,但在这种情况下,依赖实体中没有要使用的属性。 –

相关问题