在Entity Framework 7 RC 1和ASP.NET MVC 6中播种初始数据

时间:2015-12-30 19:34:23

标签: c# entity-framework asp.net-core-mvc entity-framework-core seeding

似乎在Entity Framework 7中还没有对种子数据的原生支持(https://github.com/aspnet/EntityFramework/issues/629)。

Microsoft提供的模板代码中没有DbMigrationsConfiguration类,没有Seed方法。

那么如何在使用Entity Framework 7 RC 1的ASP.NET MVC 6 Web应用程序中播种数据?

4 个答案:

答案 0 :(得分:15)

我为自己找到了一个临时的解决方法。

我们可以创建一个扩展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();
    }
}

要使用它,请将app.SeedData();行放在应用程序Configure类的Startup方法中(位于名为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
}

答案 1 :(得分:2)

我已在Seed()中创建了私有Startup.cs方法,但我也喜欢您的方法,因为它不仅可以在应用程序启动期间使用。

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 :(得分:2)

来自EF/MVC intro,只需:

  1. 依赖关系 - 将您的DbContext(下面SchoolContext)直接注入Startup.Configure() *
  2. 将您的DbContext传递给下面的函数(DbInitializer.Initialize),其功能如下:
    1. 确保数据库为created or that it's migrated; context.Database.EnsureCreated();考虑context.Database.Migrate();
    2. 如果已播种if (context.Students.Any()) { return; }
    3. 则返回
    4. 其他种子context.Students.Add({...}); context.SaveChanges();
  3. 喜欢这里:

    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. 依赖关系 - 将您的DbContext注入Startup.Configure()已在EF/MVC Intro
    2. 中完成
    3. 这里没有其他答案只是依赖注入到Configure;他们是GetService()和/或GetRequiredService(),或实例化新的 DbContext。您可能不需要那么多代码。然后,你可能需要那么多代码,(例如,如果处理了Dependency-Injected DbContext,which is where the GetService() is necessary to create a new Scope.。如果我误解了某些内容,请下载/编辑/评论。

答案 3 :(得分:1)

您可以在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; }
}

Configure()内的Startup.cs方法中,调用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);
    }