2011-06-10 35 views
62

數據庫已成功創建(與表一樣),但沒有播種。我花了幾個小時閱讀了大量的文章,但一直沒能得到它。有什麼建議麼?如何讓我的數據庫使用實體框架CodeFirst來種子?

在附註中,是否可以調用初始化程序而不在客戶端中引用我的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); 
} 
+0

您要新增種子項目的數據上下文?我知道我以前錯過了。 – 2011-06-10 22:32:06

+0

是的,我是。感謝您檢查:)。 – OpticalDelusion 2011-06-10 22:53:48

+1

= D無後顧之憂。你能否在代碼中加入一個斷點並確保你的種子被調用? – 2011-06-10 23:16:21

回答

36

這是我的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 
    } 
} 

我已經使用這個模式的幾次,它爲我工作得很好。

+2

這不是我剛剛實現的解決方案,我在上面的原始問題中詳細解釋了我的解決方案。只需發佈此評論以便將來用戶使用。感謝jdangelo的所有幫助! – OpticalDelusion 2011-06-13 19:22:28

+1

這是一個很好的方法,因爲它不需要對Application_Start()進行任何更改,因此可以重複使用 – xkingpin 2014-02-20 18:29:34

0

在你的榜樣種子事件只被解僱一旦您使用DropCreateDatabaseIfModelChanges,您可以將其更改爲DropCreateDatabaseAlways i認爲它應該每次都會發起種子事件。

編輯

這是我的DataContext

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

我試過切換。沒有運氣。仍創建數據庫和所有表,但沒有種子。 – OpticalDelusion 2011-06-10 21:55:35

+0

我調用Database.SetInitializer (new DatabaseInitializer());在爲我工作的DatabaseContext的構造函數中 – 2011-06-11 09:21:18

+0

我無法在DatabaseContext中引用DatabaseInitializer,因爲這將是一個循環引用。另外它不需要進入DatabaseContext構造函數,因爲它應該由App_Start中的DatabaseInitializer構造函數調用(據我瞭解)。 – OpticalDelusion 2011-06-13 16:48:23

0

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

如果你決定這樣做對後來通過實施基於DropCreateDatabaseIfModelChanges策略,但不修改你的模型,那麼你的Seed方法不會因爲數據庫生成打來電話,你的策略只會在下一次更改應用於您的模型。

如果您遇到這種情況,只要嘗試修改模型有點檢驗這一假設,我敢打賭,你的數據庫將被填充;)

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

10

Seed方法甚至沒有在Application_StartDatabase.SetInitializer適當的調用來調用......它的原因是非常簡單的:初始化可能是實際使用根本不會被調用,如果你還沒有任何代碼數據庫環境。

2

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

我剛剛遇到這個問題。我已經從Web.config文件中刪除了「connectionstrings」部分,並且當前該應用程序開始運行 - 沒有connectionstrings部分!我添加了該部分,並且數據庫不再播種。這不是一個合適的解決方案,但我只是在這裏添加一個數據點來解決問題。

幸運的是這只是一個小的「暴殄天物」的應用程序,我會很快放棄反正...

9

這是我可憐的小故事。

首先,經驗教訓:

  1. 種子的方法將不會被調用,直到使用的語境。
  2. 在連接調試器之前,Global.asax.cs不會在首次運行bc時運行斷點。要在 Global.asax.cs上創建斷點,您可以向Web添加一些空白區域。配置和 打一頁;那麼它會受到打擊。
  3. 如果數據庫中有VS連接 ,則播種不會發生。該應用程序會拋出一個錯誤。

因此,爲了避免悲傷:

  • 您斷開連接VS。
  • 一次切換基類DropCreateDatabaseAlways。
  • 打一個使用上下文的頁面。

現在,悲傷:

  1. 我有我的自定義初始化器類在我的Global.asax.cs文件。我的Initializer Seed方法有一個斷點;我開始申請,該方法從未受到影響。 :(
  2. 我點了破發點中的Application_Start我Database.SetInitializer電話。那些永遠不會打。:(
  3. 我意識到,我沒有DB模式的變化,所以後來我改變DropCreateDatabaseIfModelChanges到DropCreateDatabaseAlways。不過,沒什麼。:(
  4. 我終於去到使用上下文一個頁面,它的工作:/
+0

這個工作,並感謝這個有用的信息。我關閉了數據庫連接,然後切換基礎類DropCreateDatabaseAlways。它運作良好。 – 2013-02-01 08:38:48

+0

全球只有第一次運行。所以關閉IISExpress。在全局設置您的中斷點並運行。由於它的IIS應用程序級別,它會一次擊中它。 – ppumkin 2014-11-06 20:22:29

1

我也有困難得到種子()被調用而且我也感謝所有有用的建議。以上,並有一些運氣使用DropCreateDatabaseAlways ...但並不總是!!

最近,我添加下面的代碼行中我的倉庫,效果良好的構造:

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

    } 

這是足以引發種子()調用得到。如果你已經嘗試過所有的答案,但仍然沒有運氣,試試看。祝你好運,這真是一個耗時的經歷。

3

您可以撥打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" } 
     ); 
    } 
} 
0

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

我很欣賞這個問題有點老,但我最終在這裏所以別人可能會。這是我的價值:

我的數據庫創建正常,但沒有種子,即使我刪除了數據庫並使用DropDatabaseInitialiser重新啓動。

閱讀代碼後上面我發現我的上下文構造是這樣的

public MyApp_Context() 
{ 
    // some code 
} 

,而上面的例子將是我的設置

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

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

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

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

只要您不直接調用它的特定變體,就會自動調用基類的默認構造函數。有關更多詳細信息,請參閱http://stackoverflow.com/questions/13166019/will-the-base-class-constructor-be-automatically-called。 – JaredReisinger 2016-10-29 19:14:38

+0

是的,我不得不同意你的看法。唯一的是,當我三年前寫這篇文章時,我似乎已經注意到,省略(多餘)base()調用導致與包含它不同的結果。我可能會在某些時候將這些代碼挖掘出來,但假設在那裏還有其他一些效應可能是最安全的。 – Jon 2016-11-08 16:45:50

0

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

0

我遇到了同樣的問題,並在Global.asax文件和Intializer文件更改後工作。我希望它能爲那些仍然有數據播種問題的人工作。

新代碼在Global.asax中:用於初始化程序文件

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

代碼:

public class Initializer : System.Data.Entity.DropCreateDatabaseAlways<Context> 
相關問題