mburm
mburm

Reputation: 1493

Scaffold-DbContext generates wrong type

I've got an .Net6 Web API project for which the model (database first) was generated via Scaffold-DbContext from an Oracle database. Oracle contains columns with Number(4) type which was generated to byte in the C# model. It seems that the generation looks into the table, saw that the values are less then 256 and decided that byte should fit. If now a number above 256 is entered in the table the query fails.

How can I force scaffold to use a bigger type in this case?

Upvotes: 1

Views: 623

Answers (1)

onex941
onex941

Reputation: 155

In .NET 6 you can customize generated code with Handlebars templates. To do this you need to install the EntityFrameworkCore.Scaffolding.Handlebars NuGet package and then add Handlebars transformer.

After you install the NuGet package, you need to tell the dotnet ef db scaffold command to use the templates. You can do this by adding a class implementing IDesignTimeServices interface to your project. The interface has only one method to implement called ConfigureDesignTimeServices. In there you will register the Handlebars templates functionality.

using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.DependencyInjection;

namespace MyProject;

internal class MyDesignTimeService : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
    {
        serviceCollection.AddHandlebarsScaffolding();
    }
}

Now you can add HandlebarsTransformer and change the generated property type.

Let's say you want to do generate int instead of byte for only one column called MyFourDigitsColumn. You could do this by adding following transformer:

    serviceCollection.AddHandlebarsTransformers(
        propertyTransformer: p => p.PropertyName == "MyFourDigitsColumn"
            ? new EntityPropertyInfo("int", p.PropertyName, p.PropertyIsNullable)
            : p);

If you would like to do this for all types you can replace byte with int for all columns like this:

    serviceCollection.AddHandlebarsTransformers(
        propertyTransformer: p => p.PropertyType == "byte"
            ? new EntityPropertyInfo("int", p.PropertyName, p.PropertyIsNullable)
            : p);

When you now run the scaffolding now, you will notice that a new folder was created in you project called CodeTemplates and one config file.

screenshot of CodeTemplates folder

Now you can customize your generated entities and DbContext even more simply by changing the template and creating some Handlebars helpers.

For further information look at https://github.com/TrackableEntities/EntityFrameworkCore.Scaffolding.Handlebars#handlebars-helpers-and-transformers

Upvotes: 2

Related Questions