TrackableEntities / EntityFrameworkCore.Scaffolding.Handlebars

Scaffold EF Core models using Handlebars templates.
MIT License
210 stars 53 forks source link

Configuring Base Classes #92

Closed GregRotman closed 4 years ago

GregRotman commented 4 years ago

I've been using EF Core Power Tools to reverse engineer from a SSDT project's dacpac. While I was able to configure the handlebars template to generate entities that inherit from a specific base class, I'd like to be able to configure which base class to use based on either a column name that exists, or a configured list of tables (csv, or json file maybe?). Potentially control creating names that would exist in base class as well? Is this possible?

here's a contrived example of the desired entity classes:

public class EntityBase
{
public byte[] Version
public string VersionString { get => System.Text.Encoding.UTF8.GetString(Version); }
public void SetVersion (string versionString) { Version = System.Text.Encoding.GetBytes(versionString); }
}

public class EntityBaseOther
{
public void SomeOtherHelperMethod() { DoStuff(); }
}

public class Account : EntityBase
{

}
public class AccountType: EntityBaseOther
{

}
tonysneed commented 4 years ago

@GregRotman Thanks for patiently waiting for my reply. You can accomplish this by using two recently added features: excluded tables and custom template data. Just run dotnet ef dbcontext scaffold for each set of tables corresponding to a specific base class, excluding the other tables.

public void ConfigureDesignTimeServices(IServiceCollection services)
{
    // Add Handlebars scaffolding templates
    services.AddHandlebarsScaffolding(options =>
    {
        // Generate FirstEntityBase entities only
        options.ReverseEngineerOptions = ReverseEngineerOptions.EntitiesOnly;

        // Exclude non-FirstEntityBase tables
        options.ExcludedTables = new List<string> {"table3", "table4", "table5"};

        // Add custom base class for table1, table2, table3
        options.TemplateData = new Dictionary<string, object>
        {
            {"base-class", "FirstEntityBase"}
        };
    });
}

Note that you are only generating the entities, not the context. After generating all the entities, then generate the context by itself.

public void ConfigureDesignTimeServices(IServiceCollection services)
{
    // Add Handlebars scaffolding templates
    services.AddHandlebarsScaffolding(options =>
    {
        // Generate FirstEntityBase entities only
        options.ReverseEngineerOptions = ReverseEngineerOptions.DbContextOnly;
    });
}

There are other approaches you could take to accomplish the same result. But this is the most straightforward.

GregRotman commented 4 years ago

@tonysneed - That makes sense. I'll give it a try! Thank you for the guidance! Is targeting a dacpac as the scaffold source part of this project, or is that something that EF Core Power Tools is doing?

tonysneed commented 4 years ago

Be aware that with this approach you won’t be able to use the EF Core Power Tools. You can customize this way only using the command line to do the scaffolding.

GregRotman commented 4 years ago

Sure, that makes sense. Can I still scaffold from a dacpac using this approach?

tonysneed commented 4 years ago

Don't know. What are you doing via EF Core Power Tools to accomplish that?

GregRotman commented 4 years ago

Here's a reference to the reverse engineering docs https://github.com/ErikEJ/EFCorePowerTools/wiki/Reverse-Engineering

The first image shows a 'Choose Data source' and the tool allows either a database, or a dacpac

tonysneed commented 4 years ago

@ErikEJ Can he use dacpac with the EF Core CLI?

ErikEJ commented 4 years ago

No, must use Power tools for that. Considering a CLI experience later.

tonysneed commented 4 years ago

@GregRotman If you need to use the Power Tools for dacpac, then you won't be able to do any customization via ConfigureDesignTimeServices. In that case, you simply need to have different Handlbars templates for each base class you want to use. Then apply them selectively to each set of tables.

ErikEJ commented 4 years ago

Agree, Tony, that seems like the only viable option

GregRotman commented 4 years ago

Thank you Gentlemen! I greatly appreciate the guidance!