2015-10-20 109 views
2

使用复杂类型的默认列命名约定使用下划线。这意味着其类型定义的那样:实体框架的复杂类型的列命名约定

[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类型配置所有名称?

对于一些复杂的类型,我宁愿在所有的人的名字和属性使用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<ComplexTypeAttributeConvention>(new CustomComplexTypeAttributeConvention()); 

它的工作原理,但我不知道它是一个正确的方式编码: 1),那么“AddBefore”按预期工作(我不想删除默认行为调查r,只是想覆盖一个案例的默认行为)? 2)将“自定义代码”放入Apply方法或构造函数的最佳选择是哪里。

断点和ComplexTypeAttributeConvention的拆卸带来了一个想法,我们不越权“默认”的命名惯例,而是通过“所有类型的所有属性”利用“循环”。

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

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

我认为这是错误的属性修改 - 看EF源代码,这只是将类型标记为ComplexTypes(以及Complex TypeDiscoveryConvention)。我们应该寻找的是构建的ColumnName的复合类型 –

+1

这似乎是一个坏主意的惯例。这将打破,例如,EntityFramework.MappingAPI,其派生属性名称从命名,如“CONTACT_EMAIL”一栏,将其转换为一个属性搜索,如“Contact.Email”。如果联系人或电子邮件不同,它将无法找到对象上的属性,并且映射将失败。这也是包含下划线的属性或列的问题。按照惯例,最好不要使用复杂类型的列名。 – Triynko

回答

3

我从来这样做过,但它是值得一试的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<ComplexTypeAttributeConvention>(); 
    modelBuilder.Conventions.Add(new CustomComplexTypeAttributeConvention()); 
    //... 
} 
+0

谢谢。有用。但是我还有一些尚未解决的问题,你能为我解释一下吗? –

+0

我也都体现了原ComplexTypeAttributeConvention类......并没有发现默认的“强调”的行为呢?可能你知道它隐藏在哪里吗? –

+1

@RomanPokrovskij有关ComplexTypeAttributeConvention的文档非常有限。我认为删除默认并添加自定义之一在我的代码是好的。因为自定义的***从默认的继承***而不会覆盖任何事物。它只是通过'Properties()'(它是'Convention'的成员)来配置属性。我认为我们可以在'Apply'方法中做很多事情(我们可能仍然需要使用'Properties()')。我不知道为什么,但我看到一些其他人为自定义'Convention'编写代码就是这样做的。 –