Change name of Identity Column for all Entities

entity-framework entity-framework-6

Question

I want to have a "BaseEntity" class with a "Id" attribute because I am building a domain model (and some other audit tracking stuff). Every Entity in my Domain Model will derive from the BaseEntity class, with the Id attribute serving as the primary key. fairly simple concepts.....

public class BaseEntity
{
    [Key]
    public int Id { get; set; }

    public DateTime LastUpdate { get; set; }
    public string LastUpdateBy { get; set; }
}
public class Location : BaseEntity
{
    [Required]
    public string Name { get; set; }

    public string Description { get; set; }
}

I want to map the "Id" field from the aforementioned example to a "LocationId" column. I am aware that I can explicitly accomplish this for each entity using the modelBuilder by carrying out the following:

modelBuilder.Entity<Location>().Property(s => s.Id).HasColumnName("LocationId");

However, it would look terrible if I did this for each Entity in my domain model.

I attempted the following reflection, but it was unsuccessful. The compiler "cannot resolve symbol type" for some reason:

foreach (var type in GetTypesInNamespace(Assembly.Load("Domain.Model"),"Domain.Model"))
{
    modelBuilder.Entity<type>().Property(x=>x.Id).....
}

If I want to map my "Id" property to a "ClassNameId" property in the database, is there a way to specify a convention that overrides the default PrimaryKey convention? Entity Framework 6 is what I'm using.

1
1
5/7/2013 4:47:42 PM

Accepted Answer

I recommend that you look at Conventions for Custom Code First. It requires EF6, however it appears that you are already using it.
Look at the convention I used to change PascalCase names to underscore names in order to give you an insight. It contains an id property convention. An optional table name prefix is also included.

public class UnderscoreNamingConvention : IConfigurationConvention<PropertyInfo, PrimitivePropertyConfiguration>,
                                          IConfigurationConvention<Type, ModelConfiguration>
{
    public UnderscoreNamingConvention()
    {
        IdFieldName = "Id";
    }

    public string TableNamePrefix { get; set; }

    public string IdFieldName { get; set; }

    public void Apply(PropertyInfo propertyInfo, Func<PrimitivePropertyConfiguration> configuration)
    {
        var columnName = propertyInfo.Name;

        if (propertyInfo.Name == IdFieldName)
            columnName = propertyInfo.ReflectedType.Name + IdFieldName;

        configuration().ColumnName = ToUnderscore(columnName);
    }

    public void Apply(Type type, Func<ModelConfiguration> configuration)
    {
        var entityTypeConfiguration = configuration().Entity(type);
        if (entityTypeConfiguration.IsTableNameConfigured) return;

        var tableName = ToUnderscore(type.Name);

        if (!string.IsNullOrEmpty(TableNamePrefix))
        {
            tableName = string.Format("{0}_{1}", TableNamePrefix, tableName);
        }

        entityTypeConfiguration.ToTable(tableName);
    }

    public static string ToUnderscore(string value)
    {
        return Regex.Replace(value, "(\\B[A-Z])", "_$1").ToLowerInvariant();
    }
}

You employ it as such.

modelBuilder.Conventions.Add(new UnderscoreNamingConvention { TableNamePrefix = "app" });

22-Zzz: In your situation, theApply The approach should be as follows:

public void Apply(PropertyInfo propertyInfo, Func<PrimitivePropertyConfiguration> configuration)
{
    if (propertyInfo.Name == "Id")
    {
        configuration().ColumnName = propertyInfo.ReflectedType.Name + "Id";
    }
}
2
6/1/2013 12:17:53 PM

Popular Answer

In your DbContext class, try this out;

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<int>()
      .Where(p => p.Name.Equals("Id"))
      .Configure(c => c.HasColumnName(c.ClrPropertyInfo.ReflectedType.Name + "Id"));
}

The CLR Type of the fields in my primary key is int. I want to refer to every key in my code as Id, however DBAs insist that keys start with Id and the prefix for the table entity name. The information provided above is perfect for my newly established database.

You need Entity Framework 6.x.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow