entity framework复杂类型的列命名约定

使用复杂类型时,默认列命名约定使用下划线。 这意味着以这种方式定义类型:

[ColmplexType] public class Contact { string Email {get;set;} string Post {get;set;} } public EntityN { //... public Contact Contact {get;set;} } 

我们将获得以这种方式命名的列

 Contact_Email nvarchar(max) Contact_Post nvarchar(max) 

我们当然可以使用ColumnAttribute或Context.Properties映射分别配置每个列名,但是我们是否有可能创建命名约定,因此为currnet类型配置一次所有名称?

对于一些复杂的类型,我宁愿不提及属性名称(“Contact”),其他人使用CammelCase连接名称和属性,永远不会使用undersore。

讨论:

这工作(创建特定表的配置信息)

  public class CustomComplexTypeAttributeConvention : ComplexTypeAttributeConvention { public override void Apply(ConventionTypeConfiguration configuration, ComplexTypeAttribute attribute) { Properties().Where(pi => pi.DeclaringType == typeof(Contact)) .Configure(p => p.HasColumnName(p.ClrPropertyInfo.Name) ); base.Apply(configuration, attribute); } } 

和OnModelCreating

 modelBuilder.Conventions.AddBefore(new CustomComplexTypeAttributeConvention()); 

它有效,但我不确定它是否是一种正确的编码方式:1)“AddBefore”是否按预期工作(我不想删除默认行为,只想覆盖一个案例的默认行为)? 2)将“自定义代码”放入Apply方法或构造函数的最佳选项。

ComplexTypeAttributeConvention的断点和反汇编带来了一个想法,即我们不会覆盖“默认”命名约定,而是通过“所有类型的所有属性”使用“循环”。

这看起来像最坚固的解决方案,但它仍然是一个“黑客”(它不会覆盖默认的“下划线”约定,但模拟“ColumnAttribute”的呈现):

  public class BriefNameForComplexTypeConvention : Convention { public BriefNameForComplexTypeConvention() { Properties().Where(pi => pi.DeclaringType == typeof(T)) .Configure(p => p.HasColumnName(p.ClrPropertyInfo.Name) ); } } // ... modelBuilder.Conventions.Add(new BriefNameForComplexTypeConvention()); 

我以前从未这样做,但是值得尝试ComplexTypeAttributeConvention ,你可以删除默认的并将自定义的一个添加到DbModelBuilder.Conventions

 public class CustomComplexTypeAttributeConvention : ComplexTypeAttributeConvention { public CustomComplexTypeAttributeConvention(){ Properties().Configure(p => p.HasColumnName(p.ClrPropertyInfo.Name)); } } protected override void OnModelCreating(DbModelBuilder modelBuilder){ modelBuilder.Conventions.Remove(); modelBuilder.Conventions.Add(new CustomComplexTypeAttributeConvention()); //... }