如何创build一个LINQ to SQL事务?

我有一块代码涉及多个插入,但需要执行submitchanges方法之前,我完成插入其他表中,以便我可以获得一个Id。 我一直在通过互联网search,并不能find如何创build一个事务linq到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; 

编辑:忘了提及,ydc是我的datacontext

将所有东西包装在一个TransactionScope 。 在你想提交的地方调用transaction.Complete() 。 如果代码退出块而没有调用Complete() ,事务将被回滚。 但是,在查看@ s_ruchit的答案并重新检查你的代码之后,你可能会重写这个,不需要TransactionScope 。 第一个示例按照原样使用TransactionScope 。 第二个例子做了一些小的改变,但达到了相同的目的。

你需要使用TransactionScope是当你正在从数据库中读取一个值并使用它来为要添加的对象设置一个新的值的时候。 在这种情况下,LINQ交易将不会覆盖第一次读取,只是稍后提交新值。 由于您正在使用read中的值来计算写入的新值,因此您需要将read包装在同一个事务中,以确保另一个reader不计算相同的值并消除您的更改。 在你的情况下,你只是在写,所以标准的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; 

例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; } 

在使用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(); 

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

阅读文章Scott Guthrie 在这里 : – http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx