daltonwide daltonwide - 1 month ago 18
C# Question

How to customize name, length and value of a discriminator column with Entity Framework 6

I try to use EF6 with an existing database I must be compatible with.
The database has been generated by nHibernate and some tables use the table-per-hierarchy (TPH) inheritance model.

Discriminator columns are named

Category
(instead of
Discriminator
) and have an SQL length of 255 (instead of 128). Values are also different from what EF would generate.

How can I configure EF to use the existing columns (name, size and values)?

I tried to define a custom convention:

protected class DiscriminatorRenamingConvention : IStoreModelConvention<EdmProperty>
{
public void Apply(EdmProperty property, DbModel model)
{
if (property.Name == "Discriminator")
{
property.Name = "Category";
property.MaxLength = 255;
}
}
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntityA>().Map(x => x.Requires("Category").HasValue("CatA"));
modelBuilder.Entity<MyEntityB>().Map(x => x.Requires("Category").HasValue("CatB"));
modelBuilder.Conventions.Add<DiscriminatorRenamingConvention>();
base.OnModelCreating(modelBuilder);
}


This generates a column named
Category
but with a length of 128, whatever the order of instructions in the
OnModelCreating
method. Specifying category values seems to overwrite
MaxLength
.

Answer

Here

modelBuilder.Entity<MyEntityA>().Map(x => x.Requires("Category").HasValue("CatA"));

you specify the name of the discriminator to be "Category", so this

if (property.Name == "Discriminator")

will evaluate to false, hence the MaxLength will be the EF default.

To get the desired behavior, use Requires("Discriminator") and let the convention do the rest.

Comments