如何创建LINQ to SQL事务?

Dra*_*cir 67 .net transactions linq-to-sql

我有一段代码涉及多个插入但需要在我完成插入其他表之前执行submitchanges方法,以便我可以获取一个Id.我一直在搜索互联网,无法找到如何在linq to sql中创建一个事务.我已在我想要进行交易的代码中添加注释.

    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;
Run Code Online (Sandbox Code Playgroud)

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

tva*_*son 68

把整个东西包裹起来TransactionScope.transaction.Complete()在您要提交的位置调用.如果代码在未Complete()调用的情况下退出块,则将回滚事务.但是,在查看@ s_ruchit的答案并重新检查您的代码之后,您可能会将其重写为不需要TransactionScope.第一个示例使用TransactionScope您的代码.第二个示例进行了一些小的更改,但实现了相同的目的.

TransactionScope当您从数据库中读取值并使用它为要添加的对象设置新值时,您需要使用的位置.在这种情况下,LINQ事务不会覆盖第一次读取,只会覆盖新值的后续提交.由于您使用read中的值来计算写入的新值,因此需要将读取包装在同一事务中,以确保其他读取器不会计算相同的值并避免更改.在您的情况下,您只进行写入,因此标准LINQ事务应该起作用.

例1:

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;
Run Code Online (Sandbox Code Playgroud)

例2:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

  • 您将要求DTC服务在部署计算机上运行以使用TransactionScope执行事务.考虑到这一点.DTC:分布式交易协调员服务. (2认同)

thi*_*eek 40

使用LINQ to SQL时,您不需要执行显式的事务实现.默认情况下,所有数据库操作都包含在事务中.

例如:

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();
Run Code Online (Sandbox Code Playgroud)

db DataContext初始化和db.SubmitChanges()之间的所有操作都由.Net包围数据库事务,确保您的数据库保持一致并且在表之间保持属性完整性.

阅读的文章斯科特·格思里 在这里: - http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx

  • 访问ScottGu撰写的文章.您可以在没有ID的情况下关联.这就是LINQ-to-SQL的美妙之处.如果你不这样做,你就不会利用Linq-To-Sql.我建议你阅读ScottGu的文章.您可以在我的答案中找到该链接. (4认同)