2013-11-15 36 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