首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何创建LINQ to SQL事务?

如何创建LINQ to SQL事务?
EN

Stack Overflow用户
提问于 2009-04-16 11:54:50
回答 3查看 72.7K关注 0票数 69

我有一段涉及多个插入的代码,但需要在完成在其他表中插入之前执行submitchange方法,以便获取Id。我一直在互联网上搜索,但找不到如何在linq to sql中创建事务。我已经在代码中添加了我希望事务发生的注释。

代码语言:javascript
复制
    var created = false;
    try
    {
        var newCharacter = new Character();
        newCharacter.characterName = chracterName;
        newCharacter.characterLevel = 1;
        newCharacter.characterExperience = 0;
        newCharacter.userUsername = userUsername;
        newCharacter.characterClassID = ccslst[0].characterClassID;
        //Open transaction


            ydc.Characters.InsertOnSubmit(newCharacter);
            ydc.SubmitChanges();

            foreach (var ccs in ccslst)
            {
                var cs = new CharacterStat();
                cs.statId = ccs.statID;                        
                cs.statValue = ccs.statValue;
                cs.characterID = newCharacter.characterID;
                ydc.CharacterStats.InsertOnSubmit(cs);
            }                    


            var ccblst = ydc.ClassBodies.Where(cb => cb.characterClassID == newCharacter.characterClassID);
            foreach (var ccb in ccblst)
            {
                var charBody = new CharacterBody();
                charBody.bodyId = ccb.bodyId;
                charBody.bodyPartId = ccb.bodyPartId;
                charBody.characterID = newCharacter.characterID;
                ydc.CharacterBodies.InsertOnSubmit(charBody);
            }
            ydc.SubmitChanges();      
            created = true;
        //Commit transaction
        }
        catch (Exception ex)
        {
            created = false;
            //transaction Rollback;                    
        }
        return created;

编辑:忘记提到ydc是我的datacontext

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-04-16 11:56:41

将整个过程包装在一个TransactionScope中。在想要提交的地方调用transaction.Complete()。如果代码在未调用Complete()的情况下退出块,则事务将被回滚。但是,在查看了@s_ruchit的答案并重新检查了您的代码之后,您可能会重写此代码,使其不需要TransactionScope。第一个示例按原样使用代码的TransactionScope。第二个示例做了一些细微的更改,但实现了相同的目的。

当您从数据库中读取值并使用它为要添加的对象设置新值时,您需要使用TransactionScope。在这种情况下,LINQ事务将不会覆盖第一次读取,而只是稍后提交新值。由于您使用读取的值来计算写入的新值,因此需要将读取包装在相同的事务中,以确保另一个读取器不会计算相同的值,从而避免您的更改。在您的例子中,您只做写操作,所以标准的LINQ事务应该可以工作。

示例1:

代码语言:javascript
复制
var created = false;

using (var transaction = new TransactionScope())
{
    try
    {
        var newCharacter = new Character();
        newCharacter.characterName = chracterName;
        newCharacter.characterLevel = 1;
        newCharacter.characterExperience = 0;
        newCharacter.userUsername = userUsername;
        newCharacter.characterClassID = ccslst[0].characterClassID;

        ydc.Characters.InsertOnSubmit(newCharacter);
        ydc.SubmitChanges();

        foreach (var ccs in ccslst)
        {
            var cs = new CharacterStat();
            cs.statId = ccs.statID;                        
            cs.statValue = ccs.statValue;
            cs.characterID = newCharacter.characterID;
            ydc.CharacterStats.InsertOnSubmit(cs);
        }                    

        var ccblst = ydc.ClassBodies.Where(cb => cb.characterClassID == newCharacter.characterClassID);
        foreach (var ccb in ccblst)
        {
            var charBody = new CharacterBody();
            charBody.bodyId = ccb.bodyId;
            charBody.bodyPartId = ccb.bodyPartId;
            charBody.characterID = newCharacter.characterID;
            ydc.CharacterBodies.InsertOnSubmit(charBody);
        }
        ydc.SubmitChanges();      
        created = true;

        transaction.Complete();
    }
    catch (Exception ex)
    {
        created = false;
    }
}
return created;

示例2:

代码语言:javascript
复制
    try
    {
        var newCharacter = new Character();
        newCharacter.characterName = chracterName;
        newCharacter.characterLevel = 1;
        newCharacter.characterExperience = 0;
        newCharacter.userUsername = userUsername;
        newCharacter.characterClassID = ccslst[0].characterClassID;

        ydc.Characters.InsertOnSubmit(newCharacter);

        foreach (var ccs in ccslst)
        {
            var cs = new CharacterStat();
            cs.statId = ccs.statID;                        
            cs.statValue = ccs.statValue;
            newCharacter.CharacterStats.Add(cs);
        }                    

        var ccblst = ydc.ClassBodies.Where(cb => cb.characterClassID == newCharacter.characterClassID);
        foreach (var ccb in ccblst)
        {
            var charBody = new CharacterBody();
            charBody.bodyId = ccb.bodyId;
            charBody.bodyPartId = ccb.bodyPartId;
            newCharacter.CharacterBodies.Add(charBody);
        }
        ydc.SubmitChanges();      
        created = true;
    }
    catch (Exception ex)
    {
        created = false;
    }
票数 71
EN

Stack Overflow用户

发布于 2009-04-16 12:04:48

使用LINQ to SQL时,不需要执行显式事务实现。默认情况下,所有DB操作都包装在一个事务中。

例如:

代码语言:javascript
复制
AppDataContext db = new AppDataContext();

<In memory operation 1 on db>
<In memory operation 2 on db>
<In memory operation 3 on db>
<In memory operation 4 on db>

db.SubmitChanges();

数据库DataContext初始化和db.SubmitChanges()之间的所有操作都由.Net封装在一个数据库事务中,以确保您的数据库是一致的,并且具有跨表维护的属性完整性。

阅读Scott Guthrie here的一篇文章:- http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx

票数 44
EN

Stack Overflow用户

发布于 2021-09-25 15:09:30

EF6提供了Database.BeginTransaction() -一种让用户在现有DbContext中启动和完成事务本身的更容易的方法-允许在同一事务中组合几个操作,从而要么全部提交,要么全部回滚。它还允许用户更容易地指定事务的隔离级别。DbContextTransaction.Commit()方法在底层存储事务上执行提交,而DbContextTransaction.Rollback()方法在底层存储事务上执行回滚。

代码语言:javascript
复制
var created = false;
using (var ydc = new CustomContext())
{
    using (var dbContextTransaction = ydc.Database.BeginTransaction())
    {
        try
        {
            var newCharacter = new Character();
            newCharacter.characterName = chracterName;
            newCharacter.characterLevel = 1;
            newCharacter.characterExperience = 0;
            newCharacter.userUsername = userUsername;
            newCharacter.characterClassID = ccslst[0].characterClassID;
            //Open transaction

            ydc.Characters.InsertOnSubmit(newCharacter);
            ydc.SubmitChanges();

            foreach (var ccs in ccslst)
            {
                var cs = new CharacterStat();
                cs.statId = ccs.statID;
                cs.statValue = ccs.statValue;
                cs.characterID = newCharacter.characterID;
                ydc.CharacterStats.InsertOnSubmit(cs);
            }

            var ccblst = ydc.ClassBodies.Where(cb => cb.characterClassID == newCharacter.characterClassID);
            foreach (var ccb in ccblst)
            {
                var charBody = new CharacterBody();
                charBody.bodyId = ccb.bodyId;
                charBody.bodyPartId = ccb.bodyPartId;
                charBody.characterID = newCharacter.characterID;
                ydc.CharacterBodies.InsertOnSubmit(charBody);
            }
            ydc.SubmitChanges();
            created = true;
            // Commit transaction
            dbContextTransaction.Commit();
        }
        catch (Exception ex)
        {
            created = false;
            // Rollback transaction
            dbContextTransaction.Rollback();
        }
    }
}
return created;
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/755796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档