【问题标题】:Seeding Data with Entity Framework 3.0 with Model or Migration?使用带有模型或迁移的实体框架 3.0 播种数据?
【发布时间】:2019-11-05 18:00:07
【问题描述】:

使用最新的 ASP.NET Core 3 和 EF Core 3,我想像在以前版本的 EF 中所做的那样播种数据。我注意到在 Microsoft 文档中,他们将此代码作为如何播种的示例。

https://github.com/aspnet/EntityFramework.Docs/tree/master/samples/core/Modeling/DataSeeding/Migrations

它使用如下代码更新迁移:

        migrationBuilder.InsertData(
            table: "Posts",
            columns: new[] { "PostId", "BlogId", "Content", "Title", "AuthorName_First", "AuthorName_Last" },
            values: new object[] { 1, 1, "Test 1", "First post", "Andriy", "Svyryd" });

        migrationBuilder.InsertData(
            table: "Posts",
            columns: new[] { "PostId", "BlogId", "Content", "Title", "AuthorName_First", "AuthorName_Last" },
            values: new object[] { 2, 1, "Test 2", "Second post", "Diego", "Vega" });

这对我来说似乎“不舒服”,因为我学会了初始化所有数据和表的方法是删除我的迁移文件夹,然后重新创建数据库。如果我手动更新迁移,那么我将永远保持此迁移。

是否有更好的方法来处理 EF Core 3 中的种子数据?也许使用 dbContext 或以某种方式在模型类本身中添加一些东西?

【问题讨论】:

    标签: c# .net-core entity-framework-core asp-net-core-spa-services


    【解决方案1】:

    您可以在 Program.cs 中播种数据。喜欢以下。

    public static async Task Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();
    
        using (var scope = host.Services.GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            await SeedData.EnsureSeedData(scope.ServiceProvider);
        }
    
        host.Run();
    }
    

    创建一个类 SeedData 并在其中编写你的播种逻辑。

    public static async Task EnsureSeedData(IServiceProvider provider)
    {
        var dbContext = provider.GetRequiredService<MyDbContext>();
        await dbContext.Database.MigrateAsync();
    
        if(!await dbContext.MyTables.AnyAsync())
        {
            await dbContext.MyTables.AddAsync(new MyTable {})
            await dbContext.SaveChangesAsync();
        }
    }
    

    【讨论】:

    • 为什么要使用 ServiceProvider?为什么我们不能只在 Main 本身中实例化 MyDbContext?
    • @kotpal 因为我们通常在启动时注册 Dbcontext。所以它可以使用我们在那里指定的连接字符串和我们在那里使用的任何其他选项。更重要的是,如果您在单独的类库中进行迁移,我们还需要在选项中指定该程序集名称。您可以在 main 本身中初始化 Dbcontext,但您还需要在此处复制所有选项。
    • 好的。我将研究使用 ServiceProvider。现在我确实在复制选项等 - 因为我不希望 API 使用的 DbContext 必须通过迁移和播种代码。所以我将迁移和播种移到他们自己的程序集中 - 并实现 IDesignTimeDbContextFactory。我还使用 CLI 插入数据(作为从 JSON 创建但没有 ID 的 POCO)。播种需要 ID - 我使用播种来添加应用程序/系统数据。 .
    【解决方案2】:

    可能不是实际的,而是历史: MS DOCS -> Data Seeding

    简而言之:在您的上下文类中,覆盖 OnModelCreating(ModelBuilder builder)

    protected override void OnModelCreating(ModelBuilder builder)
    

    并使用这样的收缩:

    modelBuilder
      .Entity<MyEntityClass>()
         .HasData(new MyEntityClass 
             { 
                Field= 1,
                Fiekd2= "http://sample.com",
                FieldX= ...
             });
    

    【讨论】:

      猜你喜欢
      • 2013-09-16
      • 2013-08-30
      • 1970-01-01
      • 2019-06-24
      • 2023-04-09
      • 2017-04-25
      • 1970-01-01
      • 1970-01-01
      • 2014-07-08
      相关资源
      最近更新 更多