覆盖EF6自定义约定

时间:2017-06-18 16:18:40

标签: c# entity-framework entity-framework-6

前段时间我提出了一个问题about creating a custom convention for EF6,提供的答案非常顺利。

现在,我遇到了一个我正在使用它的情况,并希望覆盖特定列的值,但无法找到如何执行此操作。

这是我添加的惯例:

class ColumnPrefixConvention : IStoreModelConvention<EdmProperty>
{
    public void Apply(EdmProperty property, DbModel model) {

        string name = property.Name;

        // check if this is an ID field
        if (name == "ID") {
            return;
        }

        // Check if this is a foreignID field
        if (name.Right(2) == "ID") {
            return;
        }

        property.Name = property.DeclaringType.Name + property.Name;

    }
}

这是模型构建者:

protected override void OnModelCreating(DbModelBuilder mb) {

    mb.Conventions.Add(new ColumnPrefixConvention());

    mb.Entity<ClientRate>().Property(x => x.Rate).HasColumnName("HourlyRate");
    mb.Entity<ClientRate>().Property(x => x.EffectiveDate).HasColumnName("EffectiveDate");

}

正如您所看到的,我正在尝试覆盖不遵循惯例的HourlyRateEffectiveDate列。

我原本以为在实体属性级别指定HasColumnName将优先于约定,但事实并非如此:我收到一个无效列名错误,表明它仍在尝试使用前缀我添加的ColumnPrefixConvention的表名。

有没有人知道解决这个问题的方法?感谢

2 个答案:

答案 0 :(得分:2)

EF并不真正了解你的约定,所以它总是运行。但是在将显式配置应用于模型后,它将运行。如下所示:

    if (property.MetadataProperties.Contains("Configuration"))
    {
        //check if ColumnName has been explicitly configured
        object value = property.MetadataProperties["Configuration"].Value;
        if (value.GetType().GetProperties().Where(p => p.Name == "ColumnName").Any())
        {
            return;
        }
    }

答案 1 :(得分:0)

David Browne的代码检查是否存在ColumnName属性,但是例如,如果设置了列MaxLength属性,则该字段可以为null。

如果调用此属性的get方法,则可以获取实际名称-然后检查其是否为空。

类似:-

string GetExplicitlySetColumnName(EdmProperty item)
{
    // have we a configuration item
    if (item.MetadataProperties.Contains("Configuration"))
    {
        // get the configuration for this item
        var configuration = item.MetadataProperties["Configuration"].Value;

        // get the property info for the ColumnName property if we have one
        var properyInfo = configuration.GetType().GetProperty("ColumnName");

        if (properyInfo != null)
        {
            // if we have a column name property, return the value
            if (properyInfo.GetMethod.Invoke(configuration, null) is String columnName)
            {
                return columnName;
            }
        }
    }

    return null;
}