2013-10-07 95 views
5

我想知道,如果有人遇到類似的挑戰:生成種子代碼

我有一些數據,這是ETL'ed(進口和轉化)在那裏從Excel數據庫文件。在我的ASP.NET MVC的Web應用程序,我使用代碼優先的方法和刪除/創建每次數據庫修改:

#if DEBUG 
    Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyDataContext>()); 
#endif 

然而,由於在數據庫中的數據丟失,我不得不再次ETL它,這很煩人。

因爲數據庫只會在模型更改時被刪除,所以我將不得不調整我的ETL,我知道這一點。但我寧願更改我的數據庫種子代碼。

有沒有人知道如何獲取數據庫的內容並生成種子代碼,假設模型和SQL表都是最新的?

編輯1: 我打算使用自動生成的Configuration.cs,其種子的方法,然後用AddOrUpdate()方法將數據添加到數據庫:這裏是Microsoft's Tutorial on migrations(特別是「設置種子法「部分)。

+0

你是什麼意思的「種子代碼」? –

+0

我對我的問題添加了一個解釋。 –

回答

5

種子數據的另一種方式是在Up遷移中將其作爲sql運行。

我的代碼,將讀取的SQL文件並運行它

using System; 
using System.Data.Entity.Migrations; 
using System.IO; 

public partial class InsertStandingData : DbMigration 
{ 
    public override void Up() 
    { 
     var baseDir = AppDomain.CurrentDomain 
           .BaseDirectory 
           .Replace("\\bin", string.Empty) + "\\Data\\Sql Scripts"; 

     Sql(File.ReadAllText(baseDir + "\\StandingData.sql")); 
    } 

    public override void Down() 
    { 
     //Add delete sql here 
    } 
} 

所以,如果你的ETL爲您生成SQL,那麼你可以使用該技術。

在向上方法做的優點是

  1. 這將是比使用AddOrUpdate因爲 AddOrUpdate每次調用得到任何 已經存在的實體時查詢數據庫做更快。
  2. 您通常從已知狀態(例如空表)進入,因此您可能不需要檢查數據是否已存在。注意確保這個 然後你應該刪除Down方法中的數據,這樣你可以將 一路撕下並重新備份。
  3. 每次應用程序啓動時,Up方法都不運行。

Seed方法提供了方便 - 它具有優勢(!),它運行的每一次應用程序啓動

但是,如果你喜歡運行SQL從那裏使用的ExecuteSqlCommand代替Sql

string baseDir = AppDomain.CurrentDomain.BaseDirectory.Replace("\\bin", string.Empty) 
       + "\\Data\\Sql Scripts"; 
string path = Path.Combine(baseDir, "StandingData"); 
foreach (string file in Directory.GetFiles(path, "*.sql")) 
{ 
    context.Database.ExecuteSqlCommand(File.ReadAllText(file)); 
} 

參考文獻:

Best way to incrementally seed data

Preparing for database deployment

Database Initializer and Migrations Seed Methods

+0

Sql方法來自哪個命名空間? –

+0

它與'DbMigration'處於相同的命名空間!編輯回答以顯示課程和使用語句 – Colin

+0

So Up和Down方法僅在數據庫丟棄時運行? –

4

可以說我們有一個簡單的數據庫表,其中有記錄;

| Id | Age | FullName  | 
|------|-----|-----------------| 
| 1 | 50 | Michael Jackson | 
| 2 | 42 | Elvis Presley | 
| 3 | 48 | Whitney Houston | 
| ... | ... | ...    | 
| 3750 | 57 | Prince   | 

我們希望在我們使用自動生成的Configuration.cs文件及其Seed()方法數據庫中創建該表。

protected override void Seed(OurDbContainer context) 
{ 
    context.GreatestSingers.AddOrUpdate(
      p => p.Id, 
      new GreatestSinger { Id = 1, Age = 50, FullName = "Michael Jackson" }, 
      new GreatestSinger { Id = 2, Age = 42, FullName = "Elvis Presley" }, 
      new GreatestSinger { Id = 3, Age = 48, FullName = "Whitney Houston" } 
      ); 
} 

這是你應該做的。 次!

但是,您已在現有數據庫表中擁有此數據。所以我們可以使用這個現有的數據來創建Seed()代碼。

藉助於SQL String Concatenation;

SELECT 
CONCAT('new GreatestSinger { Id = ', Id ,', Age = ', Age ,', FullName = "', FullName ,'" },') 
FROM GreatestSinger 

會給我們所有人創造行數據所需的代碼。

只需複製/粘貼到Seed()方法。並從程序包管理器控制檯;

Add-Migration SeedDBwithSingersData 

Update-Database