4

I am using a T4 template slightly modified from the one proposed in this answer to generate typescript interfaces from my EF POCOs.

The EF Core POCOs were generated database first, and some of the database columns have default values. These are correctly mapped by the EF generator into my context, e.g. .HasDefaultValueSql("0");

I'm a little confused about how to go about accessing the default value for a given EF class, i had thought GetValueOrDefault might do the trick but that's just giving the default value for the .net type.

I see there are some other solutions out there for getting this working but i can't seem to find one that yet works with ASP .Net Core.

Ideally, i would like to know how to determine if a property has a default EF value from it's MemberInfo, as the following line from the T4 template is generating the property descriptions it would be the easiest to modify that to output a default value for the TypeScript def.

foreach (MemberInfo mi in GetInterfaceMembers(t))
{
    sb.AppendFormat("  {0}: {1};\n", mi.Name, GetTypeName(mi));
}
4
  • It would be much easier if you'll set the default value using a data-annotation attribute instead. Something like [DefaultValue("0")]. You can then easily access it using MemberInfo.CustomAttributes Commented Oct 6, 2016 at 11:55
  • Do you have access to the source DbContext inside the template? Commented Oct 6, 2016 at 11:56
  • @haim770 i am generating the classes from a database that already exists, i don't own the db and if it changes i want to be able to regenerate without examining the defaults manually Commented Oct 6, 2016 at 12:33
  • @IvanStoev sure i guess i can get access to thedbcontext inside the template, i have a mixture of EF and non EF classes that i am generating but i could easily split that into 2 templates Commented Oct 6, 2016 at 12:34

1 Answer 1

2

In case you have access to the generated DbContext, you can use the metadata provided by the DbContext.Model instead of reflection.

For instance:

foreach (var type in db.Model.GetEntityTypes())
{
    foreach (var property in type.GetProperties())
    {
        var defaultValue = property.Relational().DefaultValue;
    }
}

There are also a lot of useful methods like IModel.FindEntityType, IEnityType.FindProperty etc.

Sign up to request clarification or add additional context in comments.

7 Comments

I'm struggling to get it to reference the extension methods from RelationalMetadataExtensions in the T4 template, this code works fine in a class but i'm getting 'IProperty' does not contain a definition for 'Relational' error in the text template. any ideas?
Ah i got it i had to reference the assembly dll, and then the namespace afterwards too.
Indeed. Assemby: Microsoft.EntityFrameworkCore.Relational, Namespace: Microsoft.EntityFrameworkCore
Hmm, it's returning null for everything even though some of them definitely have default values in the context
Aha, using sql server so it's property.SqlServer().DefaultValueSql;
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.