【问题标题】:Entity Framework Code First and Collections of Primitive Types实体框架代码优先和原始类型的集合
【发布时间】:2011-11-30 23:37:49
【问题描述】:

在创建包含原始类型集合并由 EF Code First 持久化的 POCO 类时,迄今为止我发现的最佳建议是创建一个具有 ID 和原始类型的新类:

Entity Framework and Models with Simple Arrays

如果我现在有几个类需要 ObservableCollection<string> 类型的属性并将它们替换为 ObservableCollection<EntityString>(其中 EntityString 是具有 Id 和字符串属性的自定义类型),我最终会得到一个表 @987654326 @ 具有多个外键列,每个具有此类属性的具体类型的 ObservableCollection<EntityString> 类型的每个属性都有一个。

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

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

问题:

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

【问题讨论】:

    标签: entity-framework entity-framework-4.1 ef-code-first


    【解决方案1】:

    将简单类型提升为实体是一种选择。如果您想在更多关系中使用该新的原始类型实体,最好从该实体中完全删除导航属性并使用独立关联(无 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 污染,这仅用于持久性。

    【讨论】:

    • 此解决方案假定一个 ';' (或选择的任何其他魔术字符)不是基本字符串的有效输入,对吗?
    • 是否可以用类属性来表达流畅的配置WithOptional?我知道它们是相互替代的,但到目前为止还没有找到关于该主题的完整文档。
    • 如果默认映射没有使关系成为可选的,你不能用数据注释来改变它。数据注释必须放在某个属性上,但在这种情况下,依赖实体中没有要使用的属性。
    • 是的,这期望字符串中不使用该字符。如果你想使用这个字符,你必须定义某种形式的转义。
    • 有没有办法配置它,以便stringEntity.Strings.Add('foo'); 无需重新分配整个列表即可工作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多