我有一段涉及多个插入的代码,但需要在完成在其他表中插入之前执行submitchange方法,以便获取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;
编辑:忘记提到ydc是我的datacontext
发布于 2009-04-16 11:56:41
将整个过程包装在一个TransactionScope
中。在想要提交的地方调用transaction.Complete()
。如果代码在未调用Complete()
的情况下退出块,则事务将被回滚。但是,在查看了@s_ruchit的答案并重新检查了您的代码之后,您可能会重写此代码,使其不需要TransactionScope
。第一个示例按原样使用代码的TransactionScope
。第二个示例做了一些细微的更改,但实现了相同的目的。
当您从数据库中读取值并使用它为要添加的对象设置新值时,您需要使用TransactionScope
。在这种情况下,LINQ事务将不会覆盖第一次读取,而只是稍后提交新值。由于您使用读取的值来计算写入的新值,因此需要将读取包装在相同的事务中,以确保另一个读取器不会计算相同的值,从而避免您的更改。在您的例子中,您只做写操作,所以标准的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;
}
发布于 2009-04-16 12:04:48
使用LINQ to SQL时,不需要执行显式事务实现。默认情况下,所有DB操作都包装在一个事务中。
例如:
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
发布于 2021-09-25 15:09:30
EF6提供了Database.BeginTransaction()
-一种让用户在现有DbContext中启动和完成事务本身的更容易的方法-允许在同一事务中组合几个操作,从而要么全部提交,要么全部回滚。它还允许用户更容易地指定事务的隔离级别。DbContextTransaction.Commit()
方法在底层存储事务上执行提交,而DbContextTransaction.Rollback()
方法在底层存储事务上执行回滚。
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;
https://stackoverflow.com/questions/755796
复制相似问题