使用EF Core 2.2播种变量数据

时间:2018-12-18 19:13:41

标签: .net-core entity-framework-core

在我所看到的有关使用EF Core播种数据的所有示例和文章中,所有数据都是硬编码的。我需要播种一些数据,其中部分数据是可变的。我的模型是:

public class Customer
{
    [Key]
    public Guid Id { get; set; }

    public string ApiKey { get; set; }
}

具体地说,我希望ApiKey每次运行种子操作时都包含一个不同的值。这样,我为每种环境(开发,质量保证,生产)获得了不同的价值。

我创建了一种方法来生成唯一值,并将以下内容添加到我的OnModelCreating方法中。

modelBuilder.Entity<Customer>().HasData(new Customer
{
    Id = Guid.NewGuid(),
    ApiKey = GenerateApiKey()
});

您可能已经猜到,问题是对GenerateApiKey的调用是在创建迁移时发生的,因此GenerateApiKey生成的值被有效地硬编码到InsertData中打电话。

migrationBuilder.InsertData(
    table: "Customers",
    columns: new[] { "Id", "ApiKey" },
    values: new object[] 
    { 
        new Guid("bcde0c82-ad26-47fb-bd5f-1ad552d2b8f0"),
        "56+hhUTjPwz0FM9uwYg19M5rfq6aUgmNde15Frn6TFY=" 
    });

在EF 6.x中,我使用Seed子类的DbMigrationsConfiguration方法来完成此操作。

我意识到我可以修改迁移,但是我们正处于开发阶段,我们要在更改期间删除并重新创建数据库,这将要求每个开发人员在重新生成初始迁移时都记住这样做。我宁愿比它更简单。

1 个答案:

答案 0 :(得分:1)

一旦主机准备好,您就可以始终运行种子方法(这是我在2.1中的方法):

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Seed().Run();
}

...

public static class WebHostExtensions
{
    public static IWebHost Seed(this IWebHost host)
    {
        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;
            var loggerFactory = services.GetRequiredService<ILoggerFactory>();
            var context = services.GetRequiredService<MsbContext>();

            // do whatever you need here with your data before migrations
            ...
            context.Database.Migrate();

            // do whatever you need here with your data after migrations
            ...
        }
    }
}