0

Some time ago I asked a question about creating a custom convention for EF6, and the answer provided worked out quite well.

Now, I'm running into a case where I'm using this and want to override the value for a particular column, but can't find out how to do so.

Here's the convention I've added:

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;

    }
}

And here's the model builder:

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

}

As you can see, I'm trying to override the HourlyRate and EffectiveDate columns, which do not follow my convention.

I would have thought that specifying the HasColumnName on the entity property level would have taken precedence over the convention, but that's not the case: I'm getting an Invalid Column Name error that shows it's still trying to prefix the table name per the ColumnPrefixConvention I've added.

Does anyone know a way around this? Thanks

jleach
  • 7,410
  • 3
  • 33
  • 60

2 Answers2

2

EF doesn't really know what your convention does, so it always runs. But it runs after the explicit configuration has been applied to the model. So something like:

    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;
        }
    }
David Browne - Microsoft
  • 80,331
  • 6
  • 39
  • 67
0

David Browne's code checks whether there is a ColumnName property, but this could be null if, for example the columns MaxLength property is set.

If you invoke the get method of this property you can get the actual name - then check to see if it is null or not.

Something like:-

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;
}
JasonB
  • 410
  • 5
  • 7