Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Entity Naming Rule for EF

I have an edmx file in my Visual Studio project, when you insert a table from from your model into the edmx, it gets the same name as in the Database, for example, by importing myTable you get an entity called myTable with Set Name myTables.

How can I make the tables adhere to a custom naming convention when adding them to my file? So, for example, adding myTable results in an entity called tblmyTable with Set Name tblmyTables.

like image 901
PedroC88 Avatar asked Apr 24 '14 00:04

PedroC88


People also ask

What is OnModelCreating in Entity Framework?

The DbContext class has a method called OnModelCreating that takes an instance of ModelBuilder as a parameter. This method is called by the framework when your context is first created to build the model and its mappings in memory.

Which of the following is the default convention to configure a Primarykey property in EF 6 code first?

Primary Key Convention Code First infers that a property is a primary key if a property on a class is named “ID” (not case sensitive), or the class name followed by "ID". If the type of the primary key property is numeric or GUID it will be configured as an identity column.

Which of the following configures the default schema in EF core?

The default schema that EF Core uses to create database objects is dbo .

What is entity type in C#?

There are two types of Entities in Entity Framework: POCO Entities and Dynamic Proxy Entities.


1 Answers

If you are using the old Entity Object generator EF4.0 or EF5.0:

You need to modify the <YourModelName>.tt file in multiple places.

The template calls container.BaseEntitySets.OfType<EntitySet>() to get all your entity sets where the returned EntityeSet.ElementType (Where the type of ElementType is EntityType) contains the information about your entities.

These objects are used in many places in the template so the easiest solution would be to set the Name property of the EntityType. However the Name property is internal so you need to use refection to set it.

So locate the following line in your template around line 163:

region.Begin(CodeGenerationTools.GetResourceString("Template_RegionObjectSetProperties"));
foreach (EntitySet set in container.BaseEntitySets.OfType<EntitySet>())
{

And you need to add here the following code to set the Name property:

region.Begin(CodeGenerationTools.GetResourceString("Template_RegionObjectSetProperties"));
foreach (EntitySet set in container.BaseEntitySets.OfType<EntitySet>())
{
      set.ElementType.GetType()
            .GetProperty("Name", 
               BindingFlags.Instance | 
               BindingFlags.Public | 
               BindingFlags.NonPublic | 
               BindingFlags.SetProperty)
         .SetValue(set.ElementType, "tbl" + set.ElementType.Name, null);

Sadly you are not done yet because you still have to change two places:

First the generated property names are not fixed so you need to locate the following line around line line 173:

<#=code.SpaceAfter(NewModifier(set))#><#=Accessibility.ForReadOnlyProperty(set)#> ObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>> <#=code.Escape(set)#>

And change it to (Add the tbl before <#=code.Escape(set)#>:

<#=code.SpaceAfter(NewModifier(set))#><#=Accessibility.ForReadOnlyProperty(set)#> ObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>> tbl<#=code.Escape(set)#>

Because of the reflection hack you need to remove the "tbl" prefix form the generated EdmEntityTypeAttribute so you need to locate the following line around line 295:

[EdmEntityTypeAttribute(NamespaceName="<#=entity.NamespaceName#>", Name="<#=entity.Name#>")]

And change it to:

[EdmEntityTypeAttribute(NamespaceName="<#=entity.NamespaceName#>", Name="<#=entity.Name.Replace("tbl","")#>")]

If you are using the default EF DbContext generator EF5.0 or EF6.0 with edmx:

You need to modify the tt files to apply your custom naming convention.

First you should modify the <YourEdmxName>.tt file:

Around line 23 you should locate the following method call:

fileManager.StartNewFile(entity.Name + ".cs");

This method crates your entity classes so if you want to modify the generated file names you need to change it to:

fileManager.StartNewFile("tbl" + entity.Name + ".cs");

Then around line 307 you need to find the following method declaration:

public string EntityClassOpening(EntityType entity)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        _code.Escape(entity),
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}

This methods writes your class names so here you need to change it to apply your convention:

public string EntityClassOpening(EntityType entity)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        "tbl" + _code.Escape(entity), // add tbl prefix before the entity name
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}

Finally you need to modify your <YourEdmxName>.Context.tt:

Around line 296 you need to locate the following method which write out the DbSet properties:

public string DbSet(EntitySet entitySet)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} DbSet<{1}> {2} {{ get; set; }}",
        Accessibility.ForReadOnlyProperty(entitySet),
        _typeMapper.GetTypeName(entitySet.ElementType),
        _code.Escape(entitySet));
}

And change it again to apply your convention:

public string DbSet(EntitySet entitySet)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} DbSet<{1}> {2} {{ get; set; }}",
        Accessibility.ForReadOnlyProperty(entitySet),
        // add "tbl" to the type name DbSet<Table> -> DbSet<tblTable>
        "tbl" + _typeMapper.GetTypeName(entitySet.ElementType), 
        // add "tbl" to property name Tables -> tblTables
        "tbl" + _code.Escape(entitySet));
}
like image 163
nemesv Avatar answered Oct 02 '22 23:10

nemesv