在 Entity Framework 7 RC 1 和 ASP.NET MVC 6 中播种初始数据 [重复]
Posted
技术标签:
【中文标题】在 Entity Framework 7 RC 1 和 ASP.NET MVC 6 中播种初始数据 [重复]【英文标题】:Seed initial data in Entity Framework 7 RC 1 and ASP.NET MVC 6 [duplicate] 【发布时间】: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 应用程序中播种数据?
【问题讨论】:
你也可以在MSDN博客中看到这篇文章:blogs.msdn.microsoft.com/dotnet/2016/09/29/… 【参考方案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,只是:
-
将你的
DbContext
(下面的SchoolContext
)依赖注入到Startup.Configure()
*
将您的DbContext
传递给执行以下操作的函数(下面的DbInitializer.Initialize
):
-
确保数据库为created or that it's migrated;
context.Database.EnsureCreated();
考虑context.Database.Migrate();
如果已经播种则返回if (context.Students.Any()) return;
其他种子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 StudentFirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01"), ...
;
foreach (Student s in students)
context.Students.Add(s);
context.SaveChanges();
...
*依赖注入到Startup.Configure()
是我的答案值得的原因(即使已经接受了另一个答案。)
-
将
DbContext
依赖注入到Startup.Configure()
在EF/MVC Intro 中完成
这里没有其他答案,只是依赖注入到配置中;他们要么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);
【讨论】:
以上是关于在 Entity Framework 7 RC 1 和 ASP.NET MVC 6 中播种初始数据 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework Core RC2 表名复数
MVC3 Entity Framework 4.1RC @Html.DropDownListFor 如何实际工作?