web-dev-qa-db-ja.com

ASP.NET Core RC2 Seedデータベース

私の問題は、Entity Framework Coreデータベースにデータをシードしようとしていることです。私の考えでは、以下のコードは動作を示しています。これはApplicationDbContextコンストラクターで呼び出すべきではなく、startupから呼び出す必要があることに気付きましたが、これを行う方法がわかりません。

編集:Ketrexによって提供されたソリューションに基づいて、私のソリューションは次のとおりです:

Startup.cs:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        ... 

        app.ApplicationServices.GetRequiredService<ApplicationDbContext>().Seed();
    }

シード拡張:

public static class DbContextExtensions
{
    public static void Seed(this ApplicationDbContext context)
    {
        // Perform database delete and create
        context.Database.EnsureDeleted();
        context.Database.EnsureCreated();

        // Perform seed operations
        AddCountries(context);
        AddAreas(context);
        AddGrades(context);
        AddCrags(context);
        AddClimbs(context);

        // Save changes and release resources
        context.SaveChanges();
        context.Dispose();
    }

    private static void AddCountries(ApplicationDbContext context)
    {
        context.AddRange(
            new Country { Name = "England", Code = "En" },
            new Country { Name = "France", Code = "Fr" }
            );
    }

    ...
}

データベースのシードはEntityFrameworkの優先順位リストの上位にあることを理解していますが、この簡単なタスクを実行する方法、または少なくとも一時的な回避策を提供する方法に関するドキュメントがあれば素晴らしいと思います。誰かがこれを行う方法についていくつかのガイダンスを提供することができれば、それは大いにありがたいです。私は解決策に近づいていると感じていますが、それをつなぎ合わせることができません。

助けてくれてありがとう。

11
Adam H

組み込みのDIコンテナを使用していると仮定すると、これを実現する1つの方法があります。

スタートアップクラスのConfigureメソッドでシードメソッドを参照し、次のように、DbContextではなくIApplicationBuilderオブジェクトをパラメーターとして渡します。

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

次に、シードメソッドを変更してIApplicationBuilderインスタンスを受け入れます。次に、DbContextのインスタンスを起動し、次のようにシード操作を実行できます。

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
    }
}
11
cygnim

Startup.cs ConfigureServicesメソッドから使​​用して、ApplicationDbContextを使用可能にすることもできます(dbcontextをサービスとして登録する)。

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

次に、シード拡張メソッドを呼び出すConfigureメソッドの依存関係としてApplicationDbContextを追加します。

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

最後に、シードメソッドは重要なテーブルをすばやくチェックできます。おそらくdbの再作成が重すぎるためです。

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

少なくとも別の選択肢として、それがあなたや他の誰かに役立つことを願っています。

4
darmis

別のクラスライブラリからEFコードを実行し、シードを実行する場合は、次の操作を実行できます。これはTSQLを使用しています...

1)新しいクラスライブラリを作成します。 NuGetで次の依存関係を追加します...

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

2)パッケージマネージャーコンソールをこのプロジェクトに向けて実行します...

PM> add-migration Seeder01

その後...

PM> update-database

これにより、空の移行が行われます。

3)更新を次のようにスクリプト化します...

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)以前の移行に戻る...

PM> add-migration {PriorMigrationName}

シード移行をリロードし、データベースを更新します...

PM> add-migration Seeder01
PM> update-database
0
CYoung