本文介绍了实体框架复杂类型的列命名约定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

列为这样的方式

Contact_Email nvarchar(max)
Contact_Post nvarchar(max)

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

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?

对于一些复杂类型,我宁可不提及属性名称(联系人),其他连接名称和属性使用CammelCase,永远不会使用底线。

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.

讨论:

这样做(创建特定表的配置信息)

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

和OnModelCreating

and OnModelCreating

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

它有效,但我不确定是否是正确的编码方式:
1)AddBefore是否按预期工作(我不想删除默认行为,只想覆盖一种情况下的默认行为)?
2)将自定义代码放置到Apply方法或构造函数的最佳选择是哪里。

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.

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

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

这看起来像是最坚实的解决方案,但它仍然是hack(它不会覆盖默认的下划线约定,而是模拟ColumnAttribute的呈现):

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


推荐答案

我从来没有这样做,但值得尝试 ComplexTypeAttributeConvention ,可以删除默认值,并将自定义的添加到 DbModelBuilder.Conventions

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

这篇关于实体框架复杂类型的列命名约定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-26 21:18
查看更多