在实体框架 6 中更改数据库

Posted

技术标签:

【中文标题】在实体框架 6 中更改数据库【英文标题】:Alter Database in Entity Framework 6 【发布时间】:2014-02-11 10:21:32 【问题描述】:

我已在我的代码中将我的 EF 更新为 EF 6.0.2 我有以下代码行:

 applicationDbContext.Database .ExecuteSqlCommand(@"ALTER DATABASE
 CURRENT SET RECOVERY FULL;");

更新后我收到以下错误消息:

多语句中不允许使用 ALTER DATABASE 语句 交易。

我已经解决了 TransctionalBehavior 的问题,如下面的代码:

applicationDbContext.Database.ExecuteSqlCommand(
TransactionalBehavior.DoNotEnsureTransaction, @"ALTER DATABASE CURRENT SET RECOVERY FULL;");

我的问题:

为什么我在使用 EF 6 时遇到此错误? 我的解决方案是对问题的有效解决方案还是隐藏在此解决方案背后的魔鬼? 还有其他方法可以解决这个问题吗?

任何帮助将不胜感激!?

【问题讨论】:

感谢您发布解决方案,这也是我的确切问题。 【参考方案1】:

EF 6 通过 ExecuteSqlCommand 改变了事务的使用

从 Entity Framework 6.0 开始,默认情况下 ExecuteSqlCommand() 会将命令包装在事务中(如果尚未存在)。此方法的重载允许您根据需要覆盖此行为。

EF 5 的行为方式不同。你的修正是合适的。

您现在可以指定一个 TransactionalBehavior 标志来指示 EF 如何使用此命令处理事务。

var sqlCommand = String.Format("ALTER DATABASE 0 SET SINGLE_USER 
                                WITH ROLLBACK IMMEDIATE");
db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, 
                              sqlCommand);

通过使用 DoNotEnsureTransaction 标志,EF 在执行命令之前不会启动事务。这允许 ALTER DATABASE 命令成功执行。

【讨论】:

谢谢,真的很有帮助。【参考方案2】:

如果您使用 Code First 方法,可能的解决方案是

public partial class AlterDatabase : DbMigration

    public override void Up()
                                               
        Sql("ALTER DATABASE CURRENT SET RECOVERY FULL", true);
    

    public override void Down()
    

    

【讨论】:

+1 来自我,因为您是 SO 中的新手,而不是答案;-) 问题 1) 不在迁移中 2) 它来自嵌套事务。我知道上面的代码可以工作,但是当你把它放在嵌套事务中时,它会导致同样的问题。

以上是关于在实体框架 6 中更改数据库的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 6:审计/跟踪更改

使用实体框架6插入已断开的相关实体

首先在实体框架数据库中级联删除

如何在实体框架中更改数据库名称

实体框架6过滤您访问的数据

将 TransactionScope 与实体框架 6 一起使用