繁体   English   中英

如何在 Entity Framework Core 2.1 中播种枚举

[英]How to seed an enum in Entity Framework Core 2.1

我是 EF Core 的新手,正在尝试播种一个枚举。

根据Data Seeding 的说法,此功能是 EF Core 2.1 的新增功能。

我回顾了几个解决方案,包括Blake Mumford 的这个SO 解决方案,但这对我不起作用,因为枚举不是引用类型。

我的目标(在迁移的帮助下)是将 Category 枚举填充到名为 Category 的新 SQL 表中,并让我的 Payment 表包含一个将 Category 表作为外键引用的列。

任何帮助将不胜感激。 谢谢。

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);
    }
}

这就是我所做的,希望它适用于您的环境。

环境

项目框架

  • .NetCore 3.0

掘金:

  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

执行

  1. 添加 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. 创建通用枚举函数

    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. 创建接口

    public interface IEnumModel<TModel, TModelIdType> { TModelIdType Id { get; set; } string Name { get; set; } }
  4. 将接口应用到模型

    [Table("UserRoles")] public class UserRole : IEnumModel<UserRole, UserRoleEnum> { [Key] public UserRoleEnum Id { get; set; } public string Name { get; set; } }
  5. 添加您的迁移

    PM> add-migration SeedUserRoleTable

您应该会看到添加的迁移

  1. 使用种子信息更新数据库

    PM> update-database

您无法将枚举类型的值播种到数据库中,因为枚举不是实体类型,因此不会首先进入数据库。 换句话说,将没有Categories表,因此将值播种到该不存在的表中是没有意义的。

如果您实际上希望将类别保留在数据库中,则需要创建一个类似以下的类:

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

在我的 Entities 文件夹下,我添加了 Enumerations 文件夹,我有这个:

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)
        {
        }
    }

在我的 DataContext.cs 中,我只是用它来播种数据:

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

UserStatus 未在 DataContext.cs 中声明为 DbSet

.NET 核心 3.1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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