Kebechet
Kebechet

Reputation: 2417

Entity framework Core - Scaffolding enum

Context:

I use Database-first approach to generate my entities with Entity Framework Core and with use of Scaffolding. Each time I change something in the database I run Scaffolding with -f parameter to rewrite generated entities. So far so good. In my database schema I have a few Lookup tables that serve the purpose as Enums for my other tables and those other tables has Foreign key on them.

Problem:

I would like to generate from these lookup tables Enums which I can use in my code. These enums should be populated by the data in the lookup table (Id, Value). Is something like this even possible ?

I saw that one can ignore those tables from Entity generation and link their own enums with use of value-conversions. But is this really the only way around ?


Example of my database schema:

TABLE: Category

Id Value
0 Cardio
1 Strength
2 Hyperthrophy

TABLE: Exercise

Id Name Category
0 Deadlift 1
1 Benchpress 1
2 Jogging 0

So from table Category I would like to generate simple Enum:

public enum Category {
    Cardio = 0,
    Strength = 1,
    Hyperthrophy = 2
}

and then I want it to be used in the entity Exercise like:

public partial class Exercise {
    public Exercise() {
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public Category Category { get; set; }
}

Upvotes: 5

Views: 2006

Answers (2)

Gilberto Alexandre
Gilberto Alexandre

Reputation: 2367

It's not impossible, but you need to know if it's worth it. I develop using database-first, so to generate my entities I always run the scaffold tool. When I needed to customize my entities, I overrode a method that the tool uses to generate the files.

See:

[SuppressMessage("Usage", "EF1001:Internal EF Core API usage.", Justification = "<Pending>")]
public class EntityTypeGenerator : CSharpEntityTypeGenerator
{

    public EntityTypeGenerator([NotNull] IAnnotationCodeGenerator annotationCodeGenerator,
          [NotNull] ICSharpHelper cSharpHelper) :
          base(annotationCodeGenerator, cSharpHelper)
    {
    }

    public override string WriteCode(IEntityType entityType,
           string @namespace,
           bool useDataAnnotations,
           bool useNullableReferenceTypes)
    {
        var code = base.WriteCode(entityType, @namespace,
                    useDataAnnotations, useNullableReferenceTypes);

        var oldString = "public partial class " + entityType.Name;
        var newString = "public partial class " + entityType.Name + ":
                             Repositories.Infra.EntityBase";

        var newCode = code.Replace(oldString, newString);

        if (entityType.Name == "Task")
        {
            oldString = "byte StatusId ";
            newString = "Business.Models.Tarefas.EnumStatusTask StatusId ";
            newCode = code.Replace(oldString, newString);
        }

        return newCode;
    }

}

For this to work I created a separate project just for the purpose of affecting entity generation. In it I referenced the library Microsoft.EntityFrameworkCore.Design.

enter image description here

I injected my generator class inside the DesignTimeServices class implementation

public class DesignTimeServices: IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
    {
        serviceCollection.AddSingleton<ICSharpEntityTypeGenerator, EntityTypeGenerator>();
    }
}

In the main project (the runtime one, in this case the API), I referenced my new project and added the reference to the lib Microsoft.EntityFrameworkCore.Tools

teste

The following link can serve as a basis for understanding how it works and what you can do https://learn.microsoft.com/en-us/ef/core/cli/services

Upvotes: 0

JHBonarius
JHBonarius

Reputation: 11291

While this is theoretically possible to generate code based on any data, there is no tool I know of what can do what you ask at this moment.

But the real question is: why would you want this? Or better is this really wat you want?

Scaffolding is based on the database scheme, not on the table contents. The table data is and should be assumed to be dynamic. Else (i.e. if the data is static) you should question why you put it in the database at all: you could and should just put it in the code. An enum is a rather static structure.

Entity Framework is an object mapper for a relational database. So you should just use the dynamic relationships and thus the key coupling.

Upvotes: 1

Related Questions