Как можно, чтобы 2 метода доступа ADO использовали одну и ту же транзакцию? - PullRequest
0 голосов
/ 21 мая 2010

Я пишу тест, чтобы проверить, работает ли мой оператор LINQ to Entity. Я буду использовать его для других, если смогу реализовать эту концепцию.

Я хочу здесь ВСТАВИТЬзапишите с ADO, затем убедитесь, что его можно запросить с помощью LINQ, а затем ROLLBACK целиком в конце.

Я использую ADO для вставки, потому что я не хочу использовать объект или модель объектачто я тестирую.Я полагаю, что обычная ADO INSERT должна работать нормально.

проблема в том, что ... они оба используют разные типы соединений.та же транзакция, чтобы я мог откатить ее обратно *

_conn = new SqlConnection(_connectionString);
_conn.Open();

_trans = _conn.BeginTransaction();

var x = new SqlCommand("INSERT INTO Table1(ID, LastName, FirstName, DateOfBirth) values('127', 'test2', 'user', '2-12-1939');", _conn);

x.ExecuteNonQuery();     //So far, so good.  Adding a record to the table.

//at this point, we need to do **_trans.Commit()** here because our Entity code can't use the same connection. Then I have to manually delete in the TestHarness.TearDown..  I'd like to eliminate this step


//(this code is in another object, I'll include it for brevity. Imagine that I passed the connection in)
//check to see if it is there
using (var ctx = new XEntities(_conn)) //can't do this.. _conn is not an EntityConnection! 
{
    var retVal = (from m in ctx.Table1
                  where m.first_name == "test2"
                  where m.last_name == "user"
                  where m.Date_of_Birth == "2-12-1939"
                  where m.ID == 127
                  select m).FirstOrDefault();

     return (retVal != null);
 }

//Do test.. Assert.BlahBlah();

_trans.Rollback();

Ответы [ 3 ]

2 голосов
/ 21 мая 2010

Да, просто используйте TransactionScope :

using (TransactionScope ts = new TransactionScope()) {
    // Do something in ADO.NET with one connection.

    // Do something with Linq in another connection

    // Commit (or not if you want to roll back)
    //ts.Complete();
}

Никакой другой явной обработки транзакции не требуется.Обратите внимание, что если вы используете два разных соединения, вам нужно будет запустить DTC.

0 голосов
/ 22 мая 2010

Вот мой последний тест, который я создал на основе выбранного ответа. Я на самом деле тестирую сервис, который делает запрос LINQ to Entities к базе данных. (тот LINQ, который вы видели, это в основном то, что находится в сервисной функции WCF)

Таким образом, я могу вызвать службу, используя то же соединение, с которым я вставил .. (я мог бы на самом деле переместить соединение и транзакции в настройки и разбор, но это в двух словах)

   [Test]
    public void Test_VerifyXXX()
    {
        var _conn = new EntityConnection(_connectionString2);

        _conn.Open();
        EntityTransaction myTrans = _conn.BeginTransaction();

        using (var x = new XEntities(_conn))
        {
            x.ExecuteStoreCommand("INSERT INTO Table1(ID, LastName, FirstName, DateOfBirth) values('127', 'test2', 'user', '2-12-1939');");
        }             

        XService test = new XService_Mock(_conn);
        bool results = test.CustomerVerified(127, "user", "test2", new DateTime(1939, 2, 12));

        Assert.IsInstanceOf(typeof(bool), results);
        Assert.AreEqual(true, results);

        myTrans.Rollback();
    }
0 голосов
/ 21 мая 2010

Хмм ...

http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.executestorecommand(v=VS.100).aspx

_conn = new EntityConnection(_connectionString);
EntityTransaction myTrans = _conn.BeginTransaction();

using(MyObjectContext x = new MyObjectContext(_conn))
{
  x.ExecuteStoreCommand(insertString);
}

CallTest(_conn)

myTrans.Rollback();

Конечно, поскольку у вас есть объектный контекст в этот момент, вам не нужно использовать ExecuteStoreCommand, если вы вместо этого предпочитаете создать новый экземпляр данных, присоединить и сохранить изменения.

...