web-dev-qa-db-ja.com

Seed Entity Framework 7 RC 1およびASP.NET MVC 6の初期データ

Entity Framework 7では、シードデータのネイティブサポートはまだないようです( https://github.com/aspnet/EntityFramework/issues/629 )。

マイクロソフトが提供するテンプレートコードには、DbMigrationsConfigurationクラス、Seedメソッドはありません。

では、Entity Framework 7 RC 1を使用するASP.NET MVC 6 Webアプリケーションにデータをシードする方法は?

16
Nikolay Kostov

私は一時的な回避策を見つけました。

SeedDataを拡張するメソッドIApplicationBuilderを作成し、GetServiceメソッドを介してデータベースコンテキストクラスのインスタンスを取得し、それをデータのシードに使用できます。

これが私の拡張メソッドがどのように見えるかです:

_using Microsoft.AspNet.Builder;
using Microsoft.Extensions.DependencyInjection;

public static class DataSeeder
{
    // TODO: Move this code when seed data is implemented in EF 7

    /// <summary>
    /// This is a workaround for missing seed data functionality in EF 7.0-rc1
    /// More info: https://github.com/aspnet/EntityFramework/issues/629
    /// </summary>
    /// <param name="app">
    /// An instance that provides the mechanisms to get instance of the database context.
    /// </param>
    public static void SeedData(this IApplicationBuilder app)
    {
        var db = app.ApplicationServices.GetService<ApplicationDbContext>();

        // TODO: Add seed logic here

        db.SaveChanges();
    }
}
_

これを使用するには、アプリケーションConfigureクラスのStartupメソッドにapp.SeedData();行を配置します(_Startup.cs_というファイルのWebプロジェクトにあります)。

_// This method gets called by the runtime.
// Use this method to configure the HTTP request pipeline.
public void Configure(
    IApplicationBuilder app,
    IHostingEnvironment env,
    ILoggerFactory loggerFactory)
{
    app.SeedData();

    // Other configuration code
}
_
15
Nikolay Kostov

EF Core RTM 1.0およびASP.NET Core RTM 1.0

最初にシードメソッドを作成します。ここでは、現在のリクエストの範囲外であるため、手動で作成する必要があります。

_using System.Collections.Generic;
using System.Linq;
using Core1RtmEmptyTest.Entities;
using Microsoft.Extensions.DependencyInjection;

namespace Core1RtmEmptyTest.Migrations
{
    public static class ApplicationDbContextSeedData
    {
        public static void SeedData(this IServiceScopeFactory scopeFactory)
        {
            using (var serviceScope = scopeFactory.CreateScope())
            {
                var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
                if (!context.Persons.Any())
                {
                    var persons = new List<Person>
                    {
                        new Person
                        {
                            FirstName = "Admin",
                            LastName = "User"
                        }
                    };
                    context.AddRange(persons);
                    context.SaveChanges();
                }
            }

        }
    }
}
_

次に、ApplicationDbContextの正しい有効期間を指定します

_public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(ServiceLifetime.Scoped);
_

そして最後にConfigureメソッドからSeedData()メソッドを呼び出します

_public void Configure(IServiceScopeFactory scopeFactory)
{
    scopeFactory.SeedData();
_
6
VahidN

私は_Startup.cs_にプライベートSeed()メソッドを作成しましたが、アプリケーションの起動時だけでなく使用できるため、あなたのアプローチも気に入っています。

_public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    this.Seed();
}

private void Seed()
{
    using (var db = new MyDbContext())
    {
        db.Database.Migrate();

        // Seed code

        db.SaveChanges();
    }
}
_
2
George Findulov

EF/MVC intro から:

  1. 依存関係-DbContext(以下の[SchoolContext))をStartup.Configure() *に直接挿入します
  2. DbContextを次のような関数(以下の_DbInitializer.Initialize_)に渡します。
    1. データベースが createdorであることを確認 ; context.Database.EnsureCreated();考慮context.Database.Migrate();
    2. すでにシードされている場合はif (context.Students.Any()) { return; }を返します
    3. 他のシードcontext.Students.Add({...}); context.SaveChanges();

ここのような:

_public void Configure(..., ..., SchoolContext context)
{

    ...
    DbInitializer.Initialize(context);
}
_

...

_public static class DbInitializer
{
    public static void Initialize(SchoolContext context)
    {
        context.Database.EnsureCreated();

        // Look for any students.
        if (context.Students.Any())
        {
            return;   // DB has been seeded
        }

        var students = new Student[]
        {
            new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")}, ...
        };
        foreach (Student s in students)
        {
            context.Students.Add(s);
        }
        context.SaveChanges();
        ...
_

* Startup.Configure()への依存性注入が私の答えに値する理由です(別の答えがすでに受け入れられている場合でも)。

  1. DbContextStartup.Configure()への依存性注入は EF/MVC Intro で行われます
  2. ここでは、Configureに依存関係を挿入するだけの答えはありません。それらはGetService()および/またはGetRequiredService()のいずれか、または新しいDbContextをインスタンス化します。あなたはそれほど多くのコードを必要としないかもしれません。次に、再びmay必要なコードが多くなります(つまり、Dependency-Injected DbContextが破棄された場合、 これはGetService()は新しいスコープを作成するために必要です。 。私が何かについて誤っている場合は、投票/編集/コメントしてください。
2
The Red Pea

ApplicationDbContext内に静的シードメソッドを作成し、IApplicationBuilderをパラメーターとして渡すことができます。次に、このメソッドを_Startup.cs_で呼び出します。

_    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }


    public static void Seed(IApplicationBuilder applicationBuilder)
    {
        using (var context=applicationBuilder.ApplicationServices.GetRequiredService<ApplicationDbContext>())
        {
            context.Database.EnsureDeleted();
            context.Database.EnsureCreated();
            for(int i = 1; i< 1000; i++)
            {
                context.Movies.Add(new Movie
                {
                   Genre = "Action",
                   ReleaseDate =DateTime.Today,
                   Title = "Movie "+i
                });
            }
            context.SaveChanges();
        }
    }

    public DbSet<Movie> Movies { get; set; }
}
_

_Startup.cs_内のConfigure()メソッドで、ApplicationDbContext.Seed(app)を呼び出します

_      public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseIdentity();


        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
        ApplicationDbContext.Seed(app);
    }
_
1
LENG UNG