2014-02-15 43 views
6

在我們的項目中,我們有必要向數據庫添加一些預定義的數據。我認爲最好的方法和概念是用於EF遷移(不是種子方法)。EF 6遷移:如何執行sql SELECT?

但我們有添加相關數據到DB一個大麻煩:

例如:

假設我們有2個表:

用戶

  • ID( PK自動增量)
  • 名稱
  • 角色ID

角色

  • ID(PK自動遞增)
  • 名稱

讓我們假設我們需要添加用戶(名稱= '約翰', RoleId =(名稱爲'Admin'的角色的ID))。

我們該怎麼做?如果我們找到一個解決方案,這將是非常好的,它允許我們執行不使用Code First實體的純SQL SELECT腳本,因爲它們可以被修改或刪除。

對於DELETEINSERTUPDATE可用於的Sql(...)方法,但怎麼樣選擇

+0

你說的'不使用DbContext'是什麼意思? – Kaf

+0

不要做這樣的事情:\t \t \t 使用(MyDbContext的DbContext =新MyDbContext()){ 一些 代碼 \t dbContext.SaveChanges(); } – pryabov

+0

使用'ADO.NET'?順便說一句,在'SELECT'查詢之後,您不必調用'SaveChanges()'方法。 – Kaf

回答

6

您不能在遷移中創建上下文。

從邏輯上講,首先運行遷移到更新數據庫架構,然後可以通過它有一個上下文來處理數據。如果您的數據庫與模型不匹配,或者即使表格仍不存在,您也無法在EF中使用它。我不得不查看EF代碼(也因爲很好奇)。實際上,下面幾個級別的DbMigration類中的Sql()方法只是將SQL字符串添加到應執行到事務中並繼續前進的查詢列表中。它在調用時不會執行它。所以簡而言之,EF只是填寫應該立即執行的代碼行列表。如果您嘗試使用遷移代碼中C#代碼的所有功能,那麼這似乎是正確的。

這個問題其實很不錯,不幸的是我還沒有找到更好的解決方案,而不是使用純ADO。

另一種選擇是生成更多自定義SQL查詢,並更廣泛地使用T-SQL。 對於你的情況,你要插入的用戶,並設置的groupId由名稱看,它可以與內選擇使用:

INSERT INTO Users (Name, GroupId) 
VALUES ('John', RoleId = (SELECT Id FROM Roles WHERE Name = 'Admin')). 

對於我的問題,我不得不有點做更復雜的執行 - 的下列不一樣的DbSet的AddOrUpdate方法,使用IF語句:

IF EXISTS (SELECT * FROM Table1 WHERE Column1='SomeValue') 
    UPDATE Table1 SET (...) WHERE Column1='SomeValue' 
ELSE 
    INSERT INTO Table1 VALUES (...) 

我在這裏找到:http://blogs.msdn.com/b/miah/archive/2008/02/17/sql-if-exists-update-else-insert.aspx

2

我用好老LINQ此:

public override void Up() 
{ 
    using (var dc = new DbContext("your connection string or name")) 
    { 
     var ids = dc.Database.SqlQuery<int>("SELECT id FROM sometable WHERE somefield={0}", 42).ToArray(); 

     ... 
    } 
} 

使用LINQ更好,即使是通常的遷移,因爲存在DbMigration.Sql方法的錯誤,它忽略參數:How to pass parameters to DbMigration.Sql() Method

+0

出現錯誤自數據庫創建以來,支持'MyBDContext'上下文的模型已更改。' – bbodenmiller

+0

請檢查您是否正在使用來自命名空間的Linq數據庫上下文類「DbContext」 「System.Data.Entity的」。 LINQ無法讀取EF遷移,也無法拋出此類異常。這個答案的想法是使用LINQ,因爲它更簡單 – omikad

+0

這個答案的代碼中沒有LINQ:只有SQL。這很好:只是不要在LINQ時調用它。 – StriplingWarrior