CREATE DATABASE statement not allowed within multi-statement transaction

后端 未结 5 1553
不知归路
不知归路 2021-02-13 22:40

I\'m trying to build a quick test that deletes and recreates a database every time it runs. I have the following:

[TestClass]
public class PocoTest
{
    privat         


        
相关标签:
5条回答
  • 2021-02-13 23:03

    For your information, this error occurs by design and it happens whenever non-transactionable commands are issued to Microsoft SQL Server within an active transaction.

    The solution is, therefore, granting that Database.CreateIfNotExists() hits the database out of any transaction scope. Remember, SQL Profiler is your friend.

    You can get a roughly updated list of commands that are not allowed to run whithin transactions.

    Note: In case one wonders why am I providing a list based on a Sybase's product, bear in mind that Microsoft SQL Server shares most of its basic genetic with Sybase' engine. For further reading, refer to https://en.wikipedia.org/wiki/Microsoft_SQL_Server

    0 讨论(0)
  • 2021-02-13 23:08

    In case anyone else runs into this issue:

    In my Repository class, I have another definition of what's commonly labeled a "dbContext" - ProjectDataSource. This means that one context was created in my test class, while another was created in my Repository object. Sending the connectionstring to my repo class solved the problem:

    In Repository:

    public class Repository : IRepository
        {
            private readonly ProjectDataSource _db;
    
            public Repository(string connectionString)
            {
                _db = new ProjectDataSource(connectionString);   
            }
    
            public Repository()
            {
                _db = new ProjectDataSource();   
            }
    

    From my test:

    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();
            }
    
    0 讨论(0)
  • 2021-02-13 23:21

    You can not use implicit commits around certain SQL commands. Creating and Deleting databases is an example SQL server will do an AUTOCommit

    See the remarks section in the MS SQL help. http://msdn.microsoft.com/en-us/library/ms176061.aspx

    and something on Auto Commit for more info... http://msdn.microsoft.com/en-us/library/ms187878%28v=sql.105%29

    0 讨论(0)
  • 2021-02-13 23:29

    Try this code

    using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Suppress))

    {
    var sqlCommand = String.Format("Create DATABASE [{0}]", "TempBackupDB"); _context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);

    ts.Complete();

    }

    0 讨论(0)
  • 2021-02-13 23:30

    You can also use db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);

    See https://stackoverflow.com/a/24344654/375114 for details

    0 讨论(0)
提交回复
热议问题