【问题标题】:Mapping from Domain Model从领域模型映射
【发布时间】:2018-03-19 16:53:14
【问题描述】:

我有一个域模型,其中属性有自己的域类型(它们都有“值”属性来返回它们的标量值)。例如

Class FurryFrogMessage {
    public Name FurryFrogName {get; private set}
    public MaxWeight FurryFrogTopsOutAt {get; private set}
    ...
}

Class Name {
    public string Value;
    ...
}
...

现在我将我不确定哪种方法最好的领域模型中的对象持久化。

我正在使用实体框架,尝试使用带有 EF Fluent API 的域类来描述数据应如何映射到数据库表。

但是,由于我的域类的每个属性都是复杂类型,因此 Entity Framework 将列名设置为复杂类型,后跟“_Value”(复杂类型的属性)。

例如“FurryFrogName_Value”是列的名称,而我希望它是“FurryFrogName”

为了获得合理的列名,我必须为 Fluent API 中每个类的每个属性指定列名。

modelBuilder.Entity<FurryFrogMessage >()
    .Property(m => m.FurryFrogName.Value)
        .HasColumnName("FurryFrogName");
modelBuilder.Entity<FurryFrogMessage >()
    .Property(m => m.FurryFrogTopsOutAt.Value)
        .HasColumnName("FurryFrogTopsOutAt");

是否有某种方法可以自定义实体框架中的映射,以指示对于我的域类中的每个属性(这是一个复杂类型),我希望它使用属性名称和复杂类型的值属性?

还是我对实体框架的要求太高了?

(或者我应该换一种方式吗?)

【问题讨论】:

  • 嗯,据我所知,EF 使用约定来映射几乎任何内容,包括从列到名称的映射,但您使用的正是您不希望在其他表上使用的复杂类型,所以除了做你正在做的事情,我目前不知道其他方式。您可以做的一个小解决方法可能是一个通用函数,它将获取您的 &lt;TYPE&gt; 并获取它的 .Value 并将其设置为名称,因此您仍然几乎可以做您正在做的事情,只是少了很多详细地说。
  • 实体框架基于关系、键和外键。您已经描述了从 FurryFrogMessage 到 Name 的关系,因此 EF 正在创建 FK FurryFrogName_Value。如果要控制命名,则公开FK。

标签: c# entity-framework ef-fluent-api


【解决方案1】:

我会发表评论,但我缺乏声誉。

您可以尝试在实体类中使用这样的 ColumnAttribute:

[Column("CustomName")]
public MyType Name { get; set; }

还有一些代码,但更少。

【讨论】:

    【解决方案2】:

    我不熟悉实体框架,但试了一下。经过一番修改后,我创建了一个扩展方法,该方法将表达式作为参数,从正文中提取第一个属性名称并将其用作列名称。

    这是我的实现:

    public static class EntityTypeConfigurationExtensions
    {
        public static void ComplexProperty<T>(
            this EntityTypeConfiguration<T> configuration,
            Expression<Func<T, string>> expression) 
            where T : class
        {
            var columnName = expression.Body.ToString().Split('.')[1];
    
            configuration.Property(expression).HasColumnName(columnName);
        }
    }
    

    where T : class 约束来自EntityTypeConfiguration

    示例中的用法:

    modelBuilder.Entity<FurryFrogMessage>()
        .ComplexProperty(m => m.FurryFrogName.Value)
    

    另外,这里是我基于微软 EF 教程的示例的链接:https://gist.github.com/anonymous/d59d5c71787b5604bf41e021fcc53791

    它适用于 LocalDb 上的 VS2017。 EF 使用 int 类型的 BlogId 和 nvarchar(max) 类型的 Name 创建表 Blogs。

    我不确定您要使用包含值的自定义对象而不是仅使用 string 来实现什么,但我希望我的回答有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-12
      • 2011-07-03
      • 2015-11-14
      • 1970-01-01
      • 2020-01-31
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多