【问题标题】:Seed initial data in Entity Framework 7 RC 1 and ASP.NET MVC 6 [duplicate]在 Entity Framework 7 RC 1 和 ASP.NET MVC 6 中播种初始数据 [重复]
【发布时间】:2016-04-04 19:28:35
【问题描述】:

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

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

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

【问题讨论】:

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


【解决方案1】:

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

我们可以创建一个扩展IApplicationBuilder 的方法SeedData,然后通过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(); 行放在应用程序Startup 类的Configure 方法中(位于名为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
}

【讨论】:

    【解决方案2】:

    对于 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();
    

    【讨论】:

      【解决方案3】:

      我在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();
          }
      }
      

      【讨论】:

        【解决方案4】:

        来自EF/MVC intro,只是:

        1. 将你的DbContext(下面的SchoolContext)依赖注入到Startup.Configure()*
        2. 将您的DbContext 传递给执行以下操作的函数(下面的DbInitializer.Initialize):
          1. 确保数据库为created or that it's migratedcontext.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. DbContext 依赖注入到Startup.Configure()EF/MVC Intro 中完成
        2. 这里没有其他答案,只是依赖注入到配置中;他们要么GetService() 和/或GetRequiredService(),要么实例化一个新的 DbContext。您可能不需要那么多代码。再说一次,您可能需要这么多代码(即,如果已处理 Dependency-Injected DbContext,which is where the GetService() is necessary to create a new Scope.。如果我对某些事情有误,请投反对票/编辑/评论。

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 2015-06-10
            • 1970-01-01
            • 2021-10-17
            • 2016-03-31
            • 1970-01-01
            • 2014-03-07
            • 2021-06-30
            • 2015-04-28
            • 1970-01-01
            相关资源
            最近更新 更多