2013-11-15 37 views
1

作爲我的實體框架部署的一部分,我試圖將一些腳本部署到新創建的數據庫上,但是出現以下錯誤;實體框架種子部署SQL腳本錯誤

ALTER DATABASE statement not allowed within multi-statement transaction.

我的代碼;

internal sealed class Configuration : DbMigrationsConfiguration<DBContext> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = true; 
    } 

    protected override void Seed(DBContext context) 
    { 
     context.Database.ExecuteSqlCommand(
      @"ALTER DATABASE MyDB SET ENABLE_BROKER 
      CREATE QUEUE NewCarShareQueue; 
      CREATE SERVICE NewCarShareService ON QUEUE NewNewCarShareQueue 
       ([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]);"); 
    } 
} 

我已經試過以下爲好,確保只有一個事務正在經歷一次,而不是在這裏顯示,但是配置當前上下文並重新創建它;

internal sealed class Configuration : DbMigrationsConfiguration<DBContext> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = true; 
    } 

    protected override void Seed(DBContext context) 
    { 
     context.SaveChanges(); 
     context.Database.ExecuteSqlCommand(
      @"ALTER DATABASE MyDB SET ENABLE_BROKER"); 
    } 
} 

回答

2

Seed命令每個成功運行遷移後運行。即使沒有遷移掛起,它也會運行。所以這是一個糟糕的地方做任何改變的數據庫結構。

最好是創建一個遷移並在那裏執行ALTER。當模型和遷移同步時,在PM控制檯中運行add-migration EnableQueue。這會給你一個空的遷移,你現在可以添加你自己的語句。

無論如何,在Seed方法中的單獨事務中運行SQL語句是一個有趣的問題。像這樣的東西應該工作(沒有編譯它自己,所以可能有幾個錯別字吧):

protected override void Seed(DBContext context) 
{ 
    using(var tx = new TransactionScope(TransactionScopeOption.RequiresNew)) 
    using(var conn = new SqlConnection(context.Database.Connection.ConnectionString)) 
    { 
    conn.Open() 
    var command = conn.CreateCommand(); 
    command.CommandText = "ALTER DATABASE WHATEVER YOU WANT TO DO"; 
    command.ExecuteNonQuery(); 

    tx.Complete(); 
    } 
} 
+1

此,如果你刪除TransactionScope的工作。否則,我得到了同樣的錯誤:「在多語句事務中不允許ALTER DATABASE語句」 – qbik