Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
245 views
in Technique[技术] by (71.8m points)

c# - Why doesn't TransactionScope work with Entity Framework?

See the code below. If I initialize more than one entity context, then I get the following exception on the 2nd set of code only. If I comment out the second set it works.

{"The underlying provider failed on Open."}

Inner: {"Communication with the underlying transaction manager has failed."}

Inner: {"Error HRESULT E_FAIL has been returned from a call to a COM component."}

Note that this is a sample app and I know it doesn't make sense to create 2 contexts in a row. However, the production code does have reason to create multiple contexts in the same TransactionScope, and this cannot be changed.

Edit

Here is a previous question of me trying to set up MS-DTC. It seems to be enabled on both the server and the client. I'm not sure if it is set up correctly. Also note that one of the reasons I am trying to do this, is that existing code within the TransactionScope uses ADO.NET and Linq 2 Sql... I would like those to use the same transaction also. (That probably sounds crazy, but I need to make it work if possible).

How do I use TransactionScope in C#?

Solution

Windows Firewall was blocking the connections to MS-DTC.

using(TransactionScope ts = new System.Transactions.TransactionScope())
        {
                using (DatabaseEntityModel o = new DatabaseEntityModel())
                {
                    var v = (from s in o.Advertiser select s).First();
                    v.AcceptableLength = 1;
                    o.SaveChanges();
                }

                //-> By commenting out this section, it works
                using (DatabaseEntityModel o = new DatabaseEntityModel())
                {
                    //Exception on this next line
                    var v = (from s1 in o.Advertiser select s1).First();                         v.AcceptableLength = 1;
                    o.SaveChanges();
                }
                //->

                ts.Complete();
        }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can avoid using a distributed transaction by managing your own EntityConnection and passing this EntityConnection to your ObjectContext. Otherwise check out these.

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=580828&SiteID=1&mode=1 http://forums.microsoft.com/msdn/showpost.aspx?postid=113669&siteid=1&sb=0&d=1&at=7&ft=11&tf=0&pageid=1

EntityConnection conn = new EntityConnection(ConnectionString);

using (TransactionScope ts = new TransactionScope())
{
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn))
    {
            var v = (from s in o.Advertiser select s).First();
            v.AcceptableLength = 1;
    }

    //-> By commenting out this section, it works
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn))
    {
        //Exception on this next line
        var v = (from s1 in o.Advertiser select s1).First();
                v.AcceptableLength = 1;
    }
    //->

    ts.Complete();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...