2015-05-04 4 views
0

Входящая аналогия.Обновление объекта после sproc и внутри транзакции

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

Аналогия, вероятно, была бы лучше с чем-то вроде «FavoritePlaces» или «FavoriteFoods» вместо «Opinions», так как более очевидно, что они зависят от местоположения. Ну что ж. –

ответ

0

Если проследить этот код SQL Profiler вы увидите, что по умолчанию мнение не будет доступно для нового стада до trans не совершаются (я предполагаю, что вы используете уровень изоляции сервера в SQL по умолчанию в 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; 
    } 
} 
+0

Спасибо! Я проверю это, как только я снова получу проект в компилируемом состоянии (к сожалению, может быть 24 часа). –

+0

@MillieSmith сделал эту работу? –

+0

У меня еще не было возможности проверить его. У меня есть крайний срок для попадания и много кода для написания. Я проверю его как можно скорее, и если это сработает, я поднимусь и соглашусь. –

Смежные вопросы