Entity Framework (EF) T4 template modification to output PascalCasing database objects
Greetings,
So using Entity Framework (version 5 or under at least), Database First generates a model that exactly mimics the naming convention of the database objects.
So for instance, say we have the following table named :
PERSON_DETAILS
- FIRST_NAME
- LAST_NAME
- PHONE_NUMBER
If we were to run EF out-of-the-box Database First, the following model will be generated:
namespace ConsoleApp1
{
using System;
using System.Collections.Generic;public partial class PERSON_DETAILS
{
public string FIRST_NAME{ get; set; }
public string LAST_NAME { get; set; }
public string PHONE_NUMBER { get; set; }}
}
This is fine but a bit messy! Some database standard naming conventions enforce the all CAPITAL letters and underscores to denote multiple words. However in code, the PascalCasing is a more popular/readable standard.
I will post the instructions on how to modify the out of the box T4 template to do this.
- Double click on the Model1.tt T4.
- Scroll down to the class “CodeStringGenerator” and add the folllowing methods:
public string PascalCase(StructuralType type)
{
if (type == null)
{
return null;
}return PascalCase(type.Name);
}public string PascalCase(EdmMember member)
{
if (member == null)
{
return null;
}return PascalCase(member.Name);
}private string PascalCase(string name)
{
name = name.ToLowerInvariant();string result = name;
bool upperCase = false;result = string.Empty;
for (int i = 0; i < name.Length; i++)
{
if (name[i] == ‘ ‘ || name[i] == ‘_’)
{
upperCase = true;
}
else
{
if (i == 0 || upperCase)
{
result += name[i].ToString().ToUpperInvariant();
upperCase = false;
}
else
{
result += name[i];
}
}
}return result;
}
- Under the same class, find this signature method “string Property(EdmProperty edmProperty)” and modify it as such:
return string.Format(
CultureInfo.InvariantCulture,
“{0} {1} {2} {{ {3}get; {4}set; }}”,
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(PascalCase(edmProperty)),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
- Under the same class, find this signature method “string EntityClassOpening(EntityType entity)” and modify it as such:
return string.Format(
CultureInfo.InvariantCulture,
“{0} {1}partial class {2}{3}”,
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(PascalCase(entity)),
_code.StringBefore(” : “, _typeMapper.GetTypeName(entity.BaseType)));
Now save the *.tt file and immediately the model classes will be updated.
The updated model corresponding to the same table above will now look like this:
namespace ConsoleApp1
{
using System;
using System.Collections.Generic;public partial class PersonDetails
{
public string FirstName{ get; set; }
public string LastName{ get; set; }
public string PhoneNumber{ get; set; }}
}
The documentation on how to update the base T4 templates is not very prolific, so I hope that these step-by-step instructions help some people. I borrowed the pascal casing method code from this site:
http://stackoverflow.com/questions/2944974/t4-fieldname-in-camelcase-without-underscore
post back
Very useful, thanks
Hello,
tried this approach, but ran into problems as the generated code looks fine, but the other generated files (*.csdl, *.msl, *ssdl) were wrong. That files don’t know about the things you do in T4-Template which creates *.cs classes. Compilation of the Project went right, but at runtime there occured the error “The entity type [myEntityClassName] is not part of the model for the current context”
By any Chance, do you know a solution for this issue?
Regards
Joerg
Thanks. Useful solution. Is it possible to customize the generated class file names too?
There seems to be a solution for the file name customization as well..
http://stackoverflow.com/questions/24640612/entity-framework-6-t4-template-change-file-name-of-entity
Thank you it was useful, for EF6 and VS2017 i’ve made this github.com/TheTrigger/EF6-T4-CamelCase