[Entity-framework] 我怎樣才能讓我的數據庫使用實體框架CodeFirst來種子?


Answers

即使正確調用Application_Start Database.SetInitializer ,也不會調用My Seed方法...其原因很簡單:如果您尚未有任何實際使用數據庫上下文的代碼,則根本無法調用初始化程序。

Question

數據庫已成功創建(與表格一樣),但沒有播種。 我花了幾個小時閱讀了大量的文章,但一直沒能得到它。 有什麼建議麼?

在附註中,是否有可能在客戶端沒有引用我的DatabaseContext的情況下調用初始化程序?

我已經包含了所有我能想到的相關代碼。 如果有其他任何幫助,請讓我知道。

我試過的東西:

  1. 我刪除了我的連接字符串(因為無論如何默認為sqlexpress,只是名稱改變了)
  2. 我將DropCreateDatabaseIfModelChanges更改為DropCreateDatabaseAlways,仍然相同。

編輯:真正奇怪的是它曾經工作過,但我不知道如何或為什麼它再次爆發。 我假設連接字符串,但誰知道。

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>

為了文檔的緣故,我在這里分享我的解決方案。 無論如何,瀏覽所有評論將是一個痛苦。 最後,我將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);
}



更新後請注意,此答案不正確! 我的數據庫沒有得到種子的原因仍然是一個謎(但它並不缺乏默認的基礎構造函數調用,正如@JaredReisinger所指出的那樣)

我很感激這個問題有點老,但我最終在這裡等別人可能。 這是我的價值所在:

我的數據庫創建得很好,但沒有種子,即使我刪除了數據庫並使用DropDatabaseInitialiser重新啟動。

在閱讀上面的代碼後,我注意到我的上下文構造函數是這樣的

public MyApp_Context()
{
    // some code
}

而上面的例子對我的設置如下

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

是的,我沒有調用基礎對象的構造函數! 除了在這種情況下播種工作外,我不會期望任何事情,但似乎是(可重複的)情況。

注意,我實際上並不需要在基礎構造函數調用中提供上下文名稱; 我最初只是這樣寫的,因為我是在復制上述解決方案的格式。 所以我的代碼現在是這個,並且種子在初始數據庫創建時工作。

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



我也很難讓Seed()被調用。 我很欣賞上面的所有有用的建議,並使用DropCreateDatabaseAlways有一些運氣...但並不總是!

最近,我在我的Repository的構造函數中添加了以下代碼行,效果很好:

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

    }

觸發Seed()被調用就足夠了。 如果你已經嘗試過所有的答案,但仍然沒有運氣,試試看。 祝你好運,這真是一個耗時的經歷。




精心確保您不會多次聲明您的上下文變量。 如果您在播種後再次聲明,種子將被覆蓋。




您可以調用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" }
        );
    }
}



這發生在我發現Code First Features的時候。 這種情況經常發生在您首次使用Code First生成數據庫時沒有任何初始化策略。

如果您稍後決定實施基於DropCreateDatabaseIfModelChanges的策略,但不修改您的模型,那麼您的Seed方法將不會被調用,因為數據庫生成和策略只會在您下次更改模型時才應用。

如果這發生在你身上,試著修改你的模型來檢驗這個假設,我打賭你的數據庫將被填充;)

除了使用總是生成數據庫的策略外,我還沒有解決方案,但是我並沒有將初始化策略放在DbContext中,因為這個類是在生產環境中使用的,儘管初始化策略似乎主要用於流暢的開發環境。