简体   繁体   中英

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?

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.

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

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)? 2) where is the best option to put "custom code" to Apply method or to the constructor.

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".

This looks like most solid solution, but it is still a "hack" (it does not override default "underscore" convention, but emulates presents of "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 :

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());
   //...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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