2016-06-26 14 views
9

私の問題は、Entity Frameworkコアデータベースにデータをシードしようとしていることです。私はこれがApplicationDbContextコンストラクタで呼び出されるべきではなく、startupから呼び出されるべきであるが、これを行う方法がわからないことに気づいた。ASP.NET Core RC2シードデータベース

Startup.cs:

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

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

シード拡張子:

EDITは:

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

    ... 
} 

私は播種することを理解し、次のようにKetrexが提供するソリューションに基づいて、私の解決策は、データベースはEntity Frameworkの優先順位リストではかなり高いですが、この些細な作業を達成する方法や少なくとも一時的な作業を提供するためのドキュメントがあれば素晴らしいでしょう。円形。誰かがこれを行う方法に関するいくつかのガイダンスを提供することができれば、それは非常に高く評価されるだろう。私は私が解決策に近いと感じるが、ちょうど一緒にそれをまとめることはできません。

ありがとうございました。

答えて

9

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

リファレンススタートアップクラスの設定方法では、あなたのシード方法、およびこのように、代わりにDbContextのパラメータとしてIApplicationBuilderオブジェクトを渡す:

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

次に、IApplicationBuilderを受け入れるためにあなたのシード方法を変更しますインスタンス。

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 
    } 
} 
+0

ありがとうございました!この行 'app.ApplicationServices.GetRequiredService ()'は私が見逃していた行です。あなたのソリューションを少し変更して拡張メソッドとして使用しました。 –

+0

問題:context.Database.EnsureDeleted()delete __EFMigrationsHistoryも!!! –

+1

@MohammadAkbariあなたはニットを拾っているようです。 //他のシード操作 行を実行していますか?それは明らかに彼が他の操作を行うことを意味する。ここで取り上げる問題は、シードメソッドにコンテキストを注入することでした。 – Ketrex

2

あなたはまた、あなたのApplicationDbContextを利用できるようにStartup.cs ConfigureServices方法から使用することができます(登録:次に、あなたはこのように、DbContextのインスタンスをスピンアップし、あなたのシード操作を実行できるようになりますサービスとして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 Seed() 
{ 
//....  
if(context.Countries.Any()) 
    return; 
//... 
} 

:おそらくDBを再作成することは重すぎるので

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

最後にシード法は、重要なテーブルの上にクイックチェックを行うことができますオプション。

0

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

1) 新しいクラスライブラリを作成します。 はその後

PM> add-migration Seeder01 

...このプロジェクトでパッケージマネージャコンソールをポイントして実行)

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

2 ... NuGetで、次の依存関係を追加します...

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 
関連する問題