TrackableEntities / EntityFrameworkCore.Scaffolding.Handlebars

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

Ability to customise DbSet name #121

Closed birtej closed 3 years ago

birtej commented 4 years ago

Add another translator for DbSet names to allow names other than the database object name.

I have tried using a helper, but that does not change the name and hence the table 'attribute' is not generated on the entity.

tonysneed commented 4 years ago

Can you provide an example?

birtej commented 4 years ago

I am trying to use Handlebars to rescaffold to a particular naming convention in order to not have to modify thousands of lines of code (and introduce a breaking change for client-specific customisations). Tables in the database are mostly named tblXXX, but we need the DbSet properties to be named PEXXX.

I have achieved that using a handlebars helper, but we also need the [Table("tblXXX")] attribute on the entity. The inclusion of that is controlled by the DbSet name being different to the database object name, but with my helper this is not the case. An explicit option to force the attributes would be an alternative approach, but as I understand it the attribute is essential if the DbSet name is different from the table name.

so for tblAlert: ... public virtual DbSet PEAlerts { get; set; } ... [Table("tblAlerts")] public partial class PEAlert ...

My helper: Handlebars.RegisterHelper("pe-replace", (writer, context, parameters) => { var parm = parameters[0] as string; switch (parm) {

[snip] default: writer.Write(parm.Replace("tbl", "PE").Pluralize()); break; };

birtej commented 4 years ago

I have an implementation in my fork, but don't know how to meet project unit test policies.

tonysneed commented 4 years ago

Best if you create a unit test for the feature. But let me look into the issue.

tonysneed commented 4 years ago

To get the Table attribute, you will need to pass a -d or --data-annotations flag to your dotnet ef dbcontext scaffold command.

Also, you might want to consider adding Handlebars transformers.

services.AddHandlebarsTransformers(
    entityNameTransformer: n => n.Replace("Tbl", "PE"),
    entityFileNameTransformer: n => n.Replace("Tbl", "PE"),
    constructorTransformer: e => new EntityPropertyInfo(e.PropertyType.Replace("Tbl", "PE"), e.PropertyName),
    propertyTransformer: e => new EntityPropertyInfo(e.PropertyType.Replace("Tbl", "PE"), e.PropertyName),
    navPropertyTransformer: e => new EntityPropertyInfo(e.PropertyType.Replace("Tbl", "PE"), e.PropertyName));
birtej commented 4 years ago

Thanks, but the table attribute is still only included if the DbSet Name is different fro the table name and the transformers do not change the DbSet name.

tonysneed commented 4 years ago

I got the Table attribute to appear with the "tbl" prefix. The Table attribute appears when the table name does not conform to naming conventions. So a "tblCustomer" table will result in a "TblCustomer" entity, which is different, therefore requiring the Table attribute when you pass the -d flag.

As for the DbSet name, this could be handled in DbSets.hbs template, for example, with your "pe-replace" Handlebars helper method.

birtej commented 4 years ago

However, in my case, the DbSet name used to evaluate whether to include the Table attribute does comply with convention and is merely hidden by my pe-replace helper, which only changes the name rendered in the DbSet property and cannot change the DbSet name in the underlying object.

tonysneed commented 4 years ago

I thought you said your table names began with "tbl"? That does not comply with C# naming conventions for Type names, which are title cased, not camel cased.

Do you have an example repo I could look at?

tonysneed commented 4 years ago

But regardless, I can see the usefulness of a scaffolding option to force the addition of the Table attribute, regardless of whether data annotations are used. Is this what you are asking for? Would you like to submit a PR for this feature?

tonysneed commented 4 years ago

For the DbSet property name, that could be a defect, or an additional transformer could be added.

birtej commented 4 years ago

I have a changeset for an additional - just need to get out of the migration I am on today and I will fathom out how to get it up to github.

tonysneed commented 4 years ago

@birtej See these Contributing Guidelines for steps on how you should create the pull request.

tonysneed commented 4 years ago

@birtej Are you still interested in this feature?

tonysneed commented 3 years ago

I believe this will be supported natively by the EF Core tooling in v5, which I will add for #129.