Search code examples
c#.net-coreentity-framework-core.net-8.0ef-core-8.0

EF Core database first scaffold domain objects different from table names


I have an existing database that we are using EF Core and trying to generate more "business" name for our entities. I see how you can use data annotations when using the code-first model, but am not seeing a way to use this feature with the database-first model.

For example I have a table name tblStudents, but I want the entity to be Students. If I'm using code-first, I can have a file called Students.cs as shown below, and when I generate to the database it would create a table called tblStudents.

using System.ComponentModel.DataAnnotations.Schema;

namespace MyDatabase.Entities
{
    [Table("tlbStudents")]
    public class Students
    {
        public int StudentId { get; set; }
        public string? FirstName { get; set; }
        public string? LastName { get; set; }
    }
}

I want to go the other direction. I want to scaffold from the database and have it generate a file Students.cs and point to table tblStudents. With the older EF (not core), there was a wizard that you could do this with, but I'm not seeing anything in the documentation to support this.

Is it just not possible?


Solution

  • Custom Reverse Engineering Templates (available since EF Core 7) were introduced for specifically such tasks. They are based on the T4 templates.

    First install the Microsoft.EntityFrameworkCore.Templates for dotnet new:

    dotnet new install Microsoft.EntityFrameworkCore.Templates
    

    Then add templates to the project:

    dotnet new ef-templates
    

    Which will result in 2 files added to the project - DbContext.t4 and EntityType.t4:

    The DbContext.t4 template is used to scaffold a DbContext class for the database, and the EntityType.t4 template is used to scaffold entity type classes for each table and view in the database.

    Then modify them according to your needs. I believe something like the following in EntityType.t4 should do the trick (not tested):

    <#
        var actualName = EntityType.Name.Replace("tlb", "");
    #>
    [System.ComponentModel.DataAnnotations.Schema.TableAttribute("<#= EntityType.Name #>")]
    public partial class <#= actualName #>
    {