ASP.NET Core RC2 Seed Database

霸气de小男生 提交于 2019-11-29 06:18:45

Assuming you are using the built-in DI container, here is one way you can accomplish this.

Reference your seed method in the Configure method of your startup class, and pass the IApplicationBuilder object as a parameter instead of the DbContext, like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    //...
    // Put this at the end of your configure method
    DbContextSeedData.Seed(app);
}

Next, modify your seed method to accept the IApplicationBuilder instance. Then you'll be able to spin up an instance of the DbContext, and perform your seed operation, like this:

public static void Seed(IApplicationBuilder app)
{
    // Get an instance of the DbContext from the DI container
    using (var context = app.ApplicationServices.GetRequiredService<ApplicationDbContext>())
    {
        // perform database delete
        context.Database.EnsureDeleted;
        //... perform other seed operations
    }
}
darmis

You could also use from the Startup.cs ConfigureServices method to make your ApplicationDbContext available (Registering the dbcontext as a service):

public void ConfigureServices(IServiceCollection services)
{
   var connectionString = Startup.Configuration["connectionStrings:DBConnectionString"];//this line is not that relevant, the most important thing is registering the DbContext
            services.AddDbContext<ApplicationDbContext>(o => o.UseSqlServer(connectionString));
}

and then add your ApplicationDbContext as dependency in your Configure method which will call your seed extension method.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ApplicationDbContext myApplicationDbContext)
{
    //...
    myApplicationDbContext.Seed();
}

Finally the seed method could do a quick check on an important table, because perhaps recreating the db is too heavy:

public void Seed()
{
 //....      
 if(context.Countries.Any())
   return;
 //...
}

I hope it helps you or someone else, at least as another option.

If you want to run your EF code from a separate class library and do Seeding in that you can do the following. This is using TSQL...

1) Create a new class library. Add the following dependencies with NuGet...

Microsoft.AspNetCore
Microsoft.AspNetCore.Identity.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools

2) Point the Package Manager Console at this project and run...

PM> add-migration Seeder01

then...

PM> update-database

this gives you an empty migration.

3) Script the updates as something like...

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using System.IO;

namespace Test02.Data.Migrations
{
    public partial class Seeder01 : Migration
    {

        protected override void Up(MigrationBuilder migrationBuilder)
        {
            string sql = string.Empty;

            sql = "SET IDENTITY_INSERT State ON;";
            sql += "Insert into State (Id, Name) values ";
            sql += "(2, 'NSW'),";
            sql += "(3, 'VIC'),";
            sql += "(4, 'QLD'),";
            sql += "(5, 'SA')";
            sql += ";";
            sql += "SET IDENTITY_INSERT State OFF;";
            migrationBuilder.Sql(sql);

        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            string sql = string.Empty;
            sql = "delete State;";
            migrationBuilder.Sql(sql);


        }
    }
}

4) Revert to the prior migration with...

PM> add-migration {PriorMigrationName}

Reload the seed migration and update the database...

PM> add-migration Seeder01
PM> update-database
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!