我怎样才能让我的数据库使用entity frameworkCodeFirst种子?

数据库已成功创build(与表一样),但不会播种。 我花了好几个小时,读了大量的文章,但一直没有得到它。 有什么build议么?

在附注中,是否可以调用初始化程序,而不必在客户端中引用我的DatabaseContext?

我已经包含了所有我能想到的相关代码。 如果有其他事情会有所帮助,请让我知道。

我试过的东西:

  1. 我删除了我的连接string(因为它默认为sqlexpress,只是名称改变了)
  2. 我将DropCreateDatabaseIfModelChanges更改为DropCreateDatabaseAlways,仍然相同。

编辑:真奇怪的事情是一次,但我不知道如何或为什么它再次打破。 我假设连接string,但谁知道。

DatabaseInitializer.cs

public class DatabaseInitializer : DropCreateDatabaseIfModelChanges<DatabaseContext> { protected override void Seed(DatabaseContext context) { // Seeding data here context.SaveChanges(); } } 

DatabaseContext.cs

 public class DatabaseContext : DbContext { protected override void OnModelCreating(DbModelBuilder mb) { // Random mapping code } public DbSet<Entity1> Entities1 { get; set; } public DbSet<Entity2> Entities2 { get; set; } } 

Global.asax.cs – Application_Start()

 protected void Application_Start() { Database.SetInitializer<DatabaseContext>(new DatabaseInitializer()); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } 

客户端web.config

 <connectionStrings> <add name="DatabaseContext" connectionString="data source=.\SQLEXPRESS;Database=Database;Integrated Security=SSPI;" providerName="System.Data.SqlClient" /> </connectionStrings> 

为了文档的缘故,我在这里分享我的解决scheme。 浏览所有的评论将是一个痛苦无论如何。 最后,我有DatabaseInitializer和DatabaseContext在单独的类。 我不明白这些微小的变化是如何修正它的,但在这里。

DatabaseInitializer.cs

 public class DatabaseInitializer : CreateDatabaseIfNotExists<DatabaseContext> { protected override void Seed(DatabaseContext context) { // Seed code here } } 

DatabaseContext.cs

 public class DatabaseContext : DbContext { public DatabaseContext() : base("MyDatabase") { } protected override void OnModelCreating(DbModelBuilder mb) { // Code here } public DbSet<Entity> Entities { get; set; } // Other DbSets } 

Global.asax.cs – Application_Start()

 protected void Application_Start() { Database.SetInitializer(new DatabaseInitializer()); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } 

这是我的DbContext类所有的样子,他们种子就好了:

 public class MyDbContext : DbContext { public DbSet<MyClass> MyClasses { get; set; } protected override void OnModelCreating (DbModelBuilder modelBuilder) { base.OnModelCreating (modelBuilder); modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention> (); // Add any configuration or mapping stuff here } public void Seed (MyDbContext Context) { #if DEBUG // Create my debug (testing) objects here var TestMyClass = new MyClass () { ... }; Context.MyClasses.Add (TestMyClass); #endif // Normal seeding goes here Context.SaveChanges (); } public class DropCreateIfChangeInitializer : DropCreateDatabaseIfModelChanges<MyDbContext> { protected override void Seed (MyDbContext context) { context.Seed (context); base.Seed (context); } } public class CreateInitializer : CreateDatabaseIfNotExists<MyDbContext> { protected override void Seed (MyDbContext context) { context.Seed (context); base.Seed (context); } } static MyDbContext () { #if DEBUG Database.SetInitializer<MyDbContext> (new DropCreateIfChangeInitializer ()); #else Database.SetInitializer<MyDbContext> (new CreateInitializer ()); #endif } } 

我已经使用了这种模式几次,它已经很好的为我。

即使正确调用Application_Start Database.SetInitializer ,我的Seed方法也没有被调用…原因很简单:如果你还没有任何实际使用数据库上下文的代码,初始化可能根本不被调用。

这是我悲伤的小故事。

首先,经验教训:

  1. 在使用上下文之前不会调用种子方法。
  2. 在连接debugging器之前,Global.asax.cs不会在第一次运行bc时运行断点。 要在Global.asax.cs上打一个断点,你可以在Web.config中添加一些空格,然后点击一个页面; 那么它会受到打击。
  3. 如果有VS连接到数据库,播种不会发生。 该应用程序将抛出一个错误。

所以,为了避免悲伤:

  • 断开你的VS连接。
  • 一次切换基类DropCreateDatabaseAlways。
  • 打一个使用上下文的页面。

现在,悲伤:

  1. 我在我的Global.asax.cs文件中有我的自定义初始化类。 我在我的初始化种子方法有一个断点; 我开始申请,方法从未受到打击。 🙁
  2. 我在Application_Start的Database.SetInitializer调用中指向一个断点。 这从来没有受到打击。 🙁
  3. 我意识到我没有数据库模式更改,所以然后我将DropCreateDatabaseIfModelChanges更改为DropCreateDatabaseAlways。 依然没有。 🙁
  4. 我终于去了一个使用上下文的页面,它工作。 :/

您可以调用update-database手动运行Configuration类中的种子方法。 这也需要enable-migrations

 PM> update-database Specify the '-Verbose' flag to view the SQL statements being applied to the target database. No pending code-based migrations. Running Seed method. 

 internal sealed class Configuration : DbMigrationsConfiguration<ProjectManager.Data.Database.ProjectDb> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ProjectManager.Data.Database.ProjectDb context) { context.Status.AddOrUpdate( new Status() { Id = 1, Text = "New" }, new Status() { Id = 2, Text = "Working" }, new Status() { Id = 3, Text = "Completed" }, new Status() { Id = 4, Text = "Skipped" } ); } } 

Global.asax文件中的以下更改适用于我:

旧代码:

  protected void Application_Start() { Database.SetInitializer<mycontextclassname>(new DropCreateDatabaseAlways<mycontextclassname>()); ... } 

新代码:

  protected void Application_Start() { Database.SetInitializer<mycontextclassname>(new DropCreateDatabaseAlways<mycontextclassname>()); Database.SetInitializer(new Initializer()); ... } 

我也很难得到Seed()被调用。 我很欣赏上面的所有有用的build议,使用DropCreateDatabaseAlways有一些运气…但并不总是!

最近,我在我的Repository的构造函数中添加了下面这行代码,效果很好:

  public CatalogRepository() { _formCatalog.FormDescriptors.GetType(); } 

触发Seed()被调用就足够了。 如果你已经尝试了所有的答案,但仍然没有运气,试试看。 祝你好运,这是一个非常耗时的经验。

您的示例中的种子事件将只触发一次,因为您使用DropCreateDatabaseIfModelChanges可以将其更改为DropCreateDatabaseAlways我认为,它应该每次触发种子事件。

编辑

这是我的DataContext

 public WebContext() { DbDatabase.SetInitializer(new DropCreateDatabaseIfModelChanges<WebContext>()); } 

在我发现Code First Features的时候,这件事发生在我身上。 这种情况经常发生在您首次使用Code First生成数据库时没有任何初始化策略。

如果您稍后决定实施基于DropCreateDatabaseIfModelChanges的策略,但不修改您的模型,那么您的Seed方法将不会被调用,因为数据库生成和策略只会在下次更改模型时应用。

如果这发生在你身上,试着修改你的模型来testing这个假设,我敢打赌,你的数据库将被填充;)

我还没有解决scheme,除了使用一个总是生成数据库的策略,但我真的不能把这个初始化策略放在你的DbContext中,因为这个类是在你生产环境中使用的,尽pipe初始化策略似乎主要用于stream畅的开发环境。

我刚刚遇到这个问题。 我已经从Web.config文件中删除了“connectionstrings”部分,并且当前应用程序开始运行 – 没有connectionstrings部分! 我加回部分,数据库不再播种。 这不是一个合适的解决scheme,但我只是在这里添加一个数据点,以便能够解决问题。

幸运的是,这只是一个小的“一次性”应用程序,我很快就会放弃…

精心确保您不会多次声明您的上下文variables。 如果播种后再次声明,种子将被覆盖。

我遇到了同样的问题,在改变了Global.asax文件和Intializer文件之后, 希望对那些仍然有数据播种问题的人有效。

Global.asax中的新代码:

  protected void Application_Start() { Database.SetInitializer<mycontextclassname>(new DropCreateDatabaseAlways<mycontextclassname>()); Database.SetInitializer(new Initializer()); ... } 

代码为Intializer文件:

 public class Initializer : System.Data.Entity.DropCreateDatabaseAlways<Context> 

更新后注意这个答案是不正确的! 我的数据库没有得到种子的原因仍然是一个谜(但它不是缺乏默认的基础构造函数调用,由@JaredReisinger指出)

我很欣赏这个问题有点老,但是我最终还是会有其他人。 这是我的价值:

我的数据库创build正常,但没有种子,即使我删除了数据库,并使用DropDatabaseInitialiser重新启动。

在阅读上面的代码后,我注意到我的上下文构造是这样的

 public MyApp_Context() { // some code } 

而上面的例子如下我的设置

 public MyApp_Context() : base("name=MyApp_Context") { // some code } 

是的,我没有调用基础对象的构造函数! 在这种情况下,除了播种工作外,我不会期望任何事情,但似乎是(可重复的)情况。

注意,我实际上并不需要在基础构造函数调用中提供上下文名称; 我只是这样写的,因为我是在复制上面的解决scheme的格式。 所以我的代码现在是这样的,种子在初始数据库创build工作。

 public MyApp_Context() : base() { // some code }