13

データベースを実行するたびにデータベースを削除して再作成する簡単なテストを構築しようとしています。私は次のものを持っています:

[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();
        }
    }

ただし、テストを実行すると、次のエラーが発生します。

結果メッセージ: テスト メソッド 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; }
}

リポジトリ:

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

なぜこうなった?

また、違いがあれば、TestMethod の AddItem 行をコメントアウトしてもエラーは発生しません。

4

6 に答える 6

5

使用することもできますdb.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, sqlCommand);

詳細については、 https://stackoverflow.com/a/24344654/375114を参照してください

于 2016-04-08T10:56:45.137 に答える
3

他の誰かがこの問題に遭遇した場合:

私のリポジトリクラスには、一般的に「dbContext」と呼ばれるものの別の定義があります-ProjectDataSource。これは、1つのコンテキストがテストクラスで作成され、別のコンテキストがリポジトリオブジェクトで作成されたことを意味します。接続文字列をリポジトリクラスに送信すると、問題が解決しました。

リポジトリ内:

public class Repository : IRepository
    {
        private readonly ProjectDataSource _db;

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

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

私のテストから:

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();
        }
于 2013-03-02T01:36:49.337 に答える
3

特定の SQL コマンドに対して暗黙的なコミットを使用することはできません。データベースの作成と削除は、SQL サーバーがAUTOCommitを実行する例です。

MS SQL ヘルプの備考セクションを参照してください。 http://msdn.microsoft.com/en-us/library/ms176061.aspx

詳細については、自動コミットの何か... http://msdn.microsoft.com/en-us/library/ms187878%28v=sql.105%29

于 2013-03-02T09:46:03.740 に答える