传入的类比。
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;
}
}
随着一堆存储过程被调用,我想将整个群体视为脏并重新加载群体对象,但我找不到办法来做到这一点。我错过了什么?
答案 0 :(得分:0)
如果使用SQL Profiler跟踪此代码,您将看到在提交trans
之前默认意见不适用于新的群组(我假设您使用的是默认SQL Server隔离级别{ {3}})。您可以使用嵌套事务来解决此问题。
//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;
}
}