多语句事务中不允许CREATE DATABASE语句

Rob*_*ous 11 c# entity-framework

我正在尝试构建一个快速测试,每次运行时删除并重新创建数据库.我有以下内容:

[TestClass]
public class PocoTest
{
    private TransactionScope _transactionScope;
    private ProjectDataSource _dataSource; 
    private Repository _repository = new Repository();
    private const string _cstring = "Data Source=.;Initial Catalog=test_db;Trusted_Connection=True";

    [TestInitialize]
    public virtual void TestInitialize()
    {
        _dataSource = new ProjectDataSource(_cstring);
        _dataSource.Database.Delete();
        _dataSource.Database.CreateIfNotExists();
        _transactionScope = new TransactionScope();
    }
    [TestMethod]
    public void TestBasicOperations()
    {                
        var item = _repository.AddItem(new Item(){Details = "Test Item"});
        //  AddItem makes a call through the data context to add a set and then calls datacontext.SaveChanges()
    }


    [TestCleanup]
    public void TestCleanup()
    {
        // rollback
        if (_transactionScope != null)
        {
            _transactionScope.Dispose();
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是,当我运行测试时,我收到以下错误:

结果消息:测试方法Project.Repository.UnitTests.PocoTest.TestBasicOperations引发异常:System.Data.SqlClient.SqlException:多语句事务中不允许CREATE DATABASE语句.

ProjectDataSource在这里:

public class ProjectDataSource : DbContext, IProjectDataSource
{

    public ProjectDataSource() : base("DefaultConnection")
    {

    }

    public ProjectDataSource(string connectionString) : base(connectionString)
    {

    }

    public DbSet<Set> Sets { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

库:

public class Repository : IRepository
{
    private readonly ProjectDataSource _db = new ProjectDataSource();
    public Item AddItem(Item item)
        {
            _db.Items.Add(item);
            _db.SaveChanges();
            return item;
        }
}
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

此外 - 如果它有任何区别 - 如果我在TestMethod中注释掉AddItem行,则不会发生错误.

Atr*_*ige 5

你也可以使用 db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);

有关详细信息,请参阅/sf/answers/1704125811/


Jul*_*bre 5

供您参考,此错误是设计造成的,只要在活动事务中向Microsoft SQL Server发出不可事务命令,就会发生此错误。

因此,解决方案是允许Database.CreateIfNotExists()在任何事务范围之外访问数据库。请记住,SQL Profiler是您的朋友。

您可以获得粗略更新的不允许在事务中运行的命令列表

注意:如果有人想知道我为什么要提供基于 Sybase 产品的列表,请记住 Microsoft SQL Server 与 Sybase 引擎共享其大部分基本基因。如需进一步阅读,请参阅https://en.wikipedia.org/wiki/Microsoft_SQL_Server


Rob*_*ous 4

如果其他人遇到此问题:

在我的 Repository 类中,我对通常标记为“dbContext”的内容有另一个定义 - ProjectDataSource。这意味着在我的测试类中创建了一个上下文,而在我的存储库对象中创建了另一个上下文。将连接字符串发送到我的存储库类解决了问题:

在存储库中:

public class Repository : IRepository
    {
        private readonly ProjectDataSource _db;

        public Repository(string connectionString)
        {
            _db = new ProjectDataSource(connectionString);   
        }

        public Repository()
        {
            _db = new ProjectDataSource();   
        }
Run Code Online (Sandbox Code Playgroud)

从我的测试来看:

private TransactionScope _transactionScope;
        private Repository _repository;
        private ProjectDataSource _dataSource; 
        private const string _connectionString = "Data Source=.;Initial Catalog=test_db;Trusted_Connection=True";

        [TestInitialize]
        public virtual void TestInitialize()
        {
            _repository = new Repository(_connectionString);
            _dataSource = new ProjectDataSource(_connectionString);
            _dataSource.Database.Delete();
            _dataSource.Database.CreateIfNotExists();
            _transactionScope = new TransactionScope();
        }
Run Code Online (Sandbox Code Playgroud)