简体   繁体   中英

How to seed an enum in Entity Framework Core 2.1

I am new to EF Core, and am trying to seed an enum.

According to Data Seeding , this feature is new to EF Core 2.1.

I reviewed several solutions including this SO solution by Blake Mumford , but this doesn't work for me since an enum is not a reference type.

My goal (with the help from migrations) is to have the Category enum to be populated in a new SQL table called Category, and have my Payment table contain a column that references the Category table as a foreign key.

Any help would be greatly appreciated. Thanks.

public partial class Payment
{
    public int PaymentId { get; set; }
    public DateTime PostedDate { get; set; }
    public string Vendor { get; set; }
    public decimal Amount { get; set; }

    public virtual Category Category { get; set; }
}

public enum Category
{
    Restaurants,
    Groceries,
    [Display(Name = "Home Goods")]
    HomeGoods,
    Entertainment
}

public partial class MyDbContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Error: The type Category must be a reference type in order to use it as parameter TEntity in the 
        // genric type or method ModelBuilder.Entity<TEntity>()

        modelBuilder.Entity<Category>().HasData(Category.Restaurants, 
                                                Category.Groceries, 
                                                Category.HomeGoods, 
                                                Category.Entertainment);
    }
}

This is what I did hopefully it will work with your environment.

Environment

Project Framework

  • .NetCore 3.0

Nugets:

  1. EFCore 3.1.2
  2. EFCore.Design 3.1.2
  3. EFCore.Tools 3.1.2
  4. EFCore.Relational 3.1.2
  5. EFCore.SqlServer 3.1.2

Implementation

  1. Add OnModelCreating

     public partial class MyDbContext : DbContext { protected override void OnModelCreating(ModelBuilder modelBuilder) { // Error: The type Category must be a reference type in order to use it as parameter TEntity in the // genric type or method ModelBuilder.Entity<TEntity>() modelBuilder.Entity<UserRole>().HasData(EnumFunctions.GetModelsFromEnum<UserRole, UserRoleEnum>()); } }
  2. Create a Generic Enum Function

    public static class EnumFunctions { public static IEnumerable<TModel> GetModelsFromEnum<TModel, TEnum>() where TModel : IEnumModel<TModel, TEnum>, new() { var enums = new List<TModel>(); foreach (var enumVar in (TEnum[])Enum.GetValues(typeof(TEnum))) { enums.Add(new TModel { Id = enumVar, Name = enumVar.ToString() }); } return enums; } }
  3. Create an Interface

    public interface IEnumModel<TModel, TModelIdType> { TModelIdType Id { get; set; } string Name { get; set; } }
  4. Apply the interface to the model

    [Table("UserRoles")] public class UserRole : IEnumModel<UserRole, UserRoleEnum> { [Key] public UserRoleEnum Id { get; set; } public string Name { get; set; } }
  5. Add your migration

    PM> add-migration SeedUserRoleTable

You should see the migration added

  1. Update the database with the seeded info

    PM> update-database

You cannot seed values for an enum type to the database because enums are not entity types and thus do not go into the database in the first place. In other words, there will be no Categories table, so it makes no sense to seed values into that non-existent table.

If you want to actually have your categories be persisted in your database, then you need to create a class like:

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

Under my Entities folder I have added Enumerations folder, I have this:

public class UserStatus : Enumeration
    {

        public static readonly UserStatus New = new UserStatus(1, "New");
        public static readonly UserStatus UnderReview = new UserStatus(2, "UnderReview");
        public static readonly UserStatus Customer = new UserStatus(3, "Customer");
        public static readonly UserStatus Approved = new UserStatus(4, "Approved");
        public static readonly UserStatus Declined = new UserStatus(5, "Declined");

        public UserStatus(int id, string name)
                    : base(id, name)
        {
        }
    }

In my DataContext.cs I just use this to seed data:

 modelBuilder.Entity<UserStatus>().HasData(Enumeration.GetAll<UserStatus>());

UserStatus is not declared as DbSet in DataContext.cs

.NET Core 3.1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM