简体   繁体   English

实体框架复杂类型的列命名约定

[英]Entity Framework complex type's columns naming convention

Using complex types the default column naming convention uses underscore. 使用复杂类型,默认列命名约定使用下划线。 That means having type defined that way: 这意味着以这种方式定义类型:

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

public EntityN
{
    //...
    public Contact Contact {get;set;}
}

we will get columns named such way 我们将获得以这种方式命名的列

Contact_Email nvarchar(max)
Contact_Post nvarchar(max)

We of course could configure each column name separately using ColumnAttribute or Context.Properties mapping, but do we have a possibility to create naming convention and therefore configure all names in once for currnet type? 我们当然可以使用ColumnAttribute或Context.Properties映射分别配置每个列名,但是我们是否有可能创建命名约定,因此为currnet类型配置一次所有名称?

For some of complex types I would prefer do not mention property name ("Contact") at all for others connect name and attribute using CammelCase, and never would use undersore. 对于一些复杂的类型,我宁愿不提及属性名称(“Contact”),其他人使用CammelCase连接名称和属性,并且永远不会使用undersore。

Discussion: 讨论:

That works (create configuration info for specific table) 这工作(创建特定表的配置信息)

    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);
        }
    }

and OnModelCreating 和OnModelCreating

modelBuilder.Conventions.AddBefore<ComplexTypeAttributeConvention>(new CustomComplexTypeAttributeConvention());

It works, but I'm not sure is it a right way to coding: 1) does the "AddBefore" works as expected (I do not want to delete default behaviour, just want to override default behaviour for one case)? 它有效,但我不确定它是一种正确的编码方式:1)“AddBefore”是否按预期工作(我不想删除默认行为,只想覆盖一个案例的默认行为)? 2) where is the best option to put "custom code" to Apply method or to the constructor. 2)将“自定义代码”放入Apply方法或构造函数的最佳选项。

The breakpoint and disassembling of ComplexTypeAttributeConvention brings an idea that we do not override "default" naming convention but utilize "loop" through "all attributes of all types". ComplexTypeAttributeConvention的断点和反汇编带来了一个想法,即我们不会覆盖“默认”命名约定,而是通过“所有类型的所有属性”使用“循环”。

This looks like most solid solution, but it is still a "hack" (it does not override default "underscore" convention, but emulates presents of "ColumnAttribute"): 这看起来像最可靠的解决方案,但它仍然是一个“黑客”(它不会覆盖默认的“下划线”约定,但模拟“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>());

I've never done this before but it's worth trying the ComplexTypeAttributeConvention , you can remove the default one and add the custom one to DbModelBuilder.Conventions : 我之前从未这样做过,但是值得尝试一下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());
   //...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM