我有一个域模型,其中属性具有自己的域类型(它们都具有返回其标量值的"Value"属性)。 例如
Class FurryFrogMessage {
public Name FurryFrogName {get; private set}
public MaxWeight FurryFrogTopsOutAt {get; private set}
...
}
Class Name {
public string Value;
...
}
...
现在,我将对象持久化在域模型中,我不确定哪种方法是最好的方法。
我正在使用实体框架,尝试将域类与 EF Fluent API 一起使用,以描述数据应如何映射到数据库表。
但是,由于我的域类的每个属性都是复杂类型,因此实体框架将列名设置为复杂类型,后跟"_Value"(复杂类型的属性)。
例如,"FurryFrogName_Value"是列的名称,而我希望它是"毛茸茸的青蛙名称">
为了获得合理的列名,我必须为 Fluent API 中每个类的每个属性指定列名。
modelBuilder.Entity<FurryFrogMessage >()
.Property(m => m.FurryFrogName.Value)
.HasColumnName("FurryFrogName");
modelBuilder.Entity<FurryFrogMessage >()
.Property(m => m.FurryFrogTopsOutAt.Value)
.HasColumnName("FurryFrogTopsOutAt");
有没有办法自定义实体框架中的映射,以指示对于域类中的每个属性(复杂类型),我希望它使用属性的名称和复杂类型的值属性?
还是我对实体框架的要求过高?
(或者我应该以另一种方式这样做吗?
我会评论,但我缺乏声誉。
您可以尝试在实体类中使用如下所示的 ColumnAttribute:
[Column("CustomName")]
public MyType Name { get; set; }
仍然有一些代码,但更少。
我不熟悉实体框架,但试了一下。经过一些修补,我制作了一个扩展方法,该方法将表达式作为参数,从主体中提取第一个属性名称并将其用作列名。
这是我的实现:
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)
另外,这是基于Microsoft EF教程的示例的链接:https://gist.github.com/anonymous/d59d5c71787b5604bf41e021fcc53791
它适用于LocalDb上的VS2017。EF 创建表博客,其中包含 int 类型的 BlogId 列和 nvarchar(max) 类型的 Name。
我不确定您要使用包含值的自定义对象而不是仅使用string
来实现什么,但我希望我的答案有所帮助。