即将到来的类比。
class Herd
{
public List<Animal> Animals { get; set; }
}
class Animal
{
//at least for today, animals have opinions
public List<Opinion> Opinions { get; set; }
}
class Opinion { }我们希望一次性地将不同的牛群从美国东部转移到美国西部。我们为我们移动的每个羊群创建一个事务。在该事务中,我们调用了一些存储过程。其中一个给动物添加了一些默认的观点。稍后,在同一事务中的C#代码中,我们手动向动物添加意见,但它们依赖于默认意见。
using (var trans = _context.Database.BeginTransaction())
{
try
{
_context.Herds.Add(herd);
_context.SaveChanges();
Proc1Wrapper(herd);
Proc2Wrapper(herd);
Proc3Wrapper(herd);
InsertDefaultOpinionsProc(herd);
//this does not load the default opinions:
herd = _context.Herds.Where(o => o.HerdID == herd.ID).First();
//this does not either:
herd = _context.Herds.Find(herd.ID);
//this doesn't either:
_context.Entry(herd).Reload();
//this **does** load the default opinions
foreach (var animal in herd.Animals)
_context.Entry(animal).Collection("Opinions").Load();
//dependent on default opinions
AddOpinionsManually(herd);
_context.SaveChanges();
trans.Commit();
}
catch
{
trans.Rollback();
throw;
}
}在调用了一堆存储过程的情况下,我希望将整个群组视为脏对象并重新加载群组对象,但我找不到这样做的方法。我遗漏了什么?
发布于 2015-05-05 07:50:44
如果您使用SQL Profiler跟踪这段代码,您将看到在提交trans之前,默认意见将不适用于新的群组(我假设您使用的是默认的SQL Server隔离级别ReadCommitted)。您可以通过使用嵌套事务来解决此问题。
//this will start a new transaction
using (var trans = new TransactionScope(TransactionScopeOption.RequiresNew))
{
try
{
_context.Herds.Add(herd);
_context.SaveChanges();
//this will use the "ambient" transaction but can commit separately
using (wrapperTransaction = new TransactionScope(TransactionScopeOption.Required))
{
Proc1Wrapper(herd);
Proc2Wrapper(herd);
Proc3Wrapper(herd);
InsertDefaultOpinionsProc(herd);
wrapperTransaction.Commit() //now your default opinions are inserted into the db
}
//this should return the herd now fully opinionated :)
herd = _context.Herds.First(o => o.HerdID == herd.ID);
AddOpinionsManually(herd);
_context.SaveChanges();
trans.Commit();
}
catch
{
trans.Rollback();
throw;
}
}https://stackoverflow.com/questions/30039889
复制相似问题