如何让2个ADO访问方法使用相同的事务?

时间:2010-05-21 19:39:29

标签: entity-framework ado.net transactions

我正在编写一个测试,看看我的LINQ to Entity语句是否有效......如果我能够理解这个概念,我会将其用于其他人。

我的目的是用ADO插入一条记录,然后验证它是否可以用LINQ查询,然后在最后ROLLBACK整个事情。

我正在使用ADO插入,因为我不想使用我正在测试的对象或实体模型。我认为普通的ADO INSERT应该可以。

问题是......他们都使用不同类型的连接。

是否可以让这两种不同的数据访问方法使用相同的TRANSACTION,以便我可以回滚?

_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 个答案:

答案 0 :(得分:2)

是的,只需使用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。

答案 1 :(得分:0)

嗯...

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。

答案 2 :(得分:0)

这是我根据我选择的答案创建的最终测试。我实际上正在测试一个使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();
    }