У меня есть два класса. Первый представляет собой основные данные, второй представляет его подробные данные (они связаны через внешние ключи). Поскольку для записи подробных данных требуется существующая основная запись, сначала необходимо сохранить основную запись. К сожалению, ошибки могут возникать при сохранении подробных данных, поэтому я должен откатить сохранение мастера и в случае ошибки.Как использовать комбинированные транзакции в Entity Framework 6
У меня есть следующий код.
Мастер-класс:
MyDataContext db=new MyDataContext();
DetailData detail=new DetailData();
using (var transaction= db.Database.BeginTransaction())
{
try
{
//db.Database.CommandTimeout = 10;
db.SaveChanges();
//saving details
detail.SaveData(masterId);
//on success
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
}
Подробный класс:
MyDataContext db;
DataItem dataItem;
public DetailData()
{
db=new MyDataContext();
dataItem=new DataItem();
db.DataItem.Attach(dataItem);
}
public SaveData(int id)
{
dataItem.Master_ID=id;
db.SaveChanges();
}
Как это best practice by Microsoft использовать DataContext по требованию, я не хочу, чтобы передать существующий контекст в подробных данных.
В общем случае экземпляр DataContext рассчитан на то, чтобы продлиться один «блок работы», однако ваше приложение определяет этот термин. DataContext легкий и не дорогой в создании. Типичное приложение LINQ to SQL создает экземпляры DataContext в области методов или как член краткосрочных классов , которые представляют собой логический набор связанных операций базы данных .
К сожалению, я получаю исключение в таймаута как основной сделки пока не совершил, и я начинаю новый SaveChanges
на другом объекте контекста.
Если я использую db.DataBase.UseTransaction
и передаю транзакцию мастер-класса, я получаю другое исключение из-за транзакции , принадлежащей другому контексту.
Итак, как я могу объединить сохранение данных мастера и детали в одну рабочую транзакцию?
Если ваши объекты связаны внешним ключом, и это отношение известно EF, то почему вы не можете просто добавить 'Detail' в' Master' и вызвать 'SaveChanges'? EF сделает для вас тяжелую работу (он будет делать обновления в правильном порядке и помещает все это в транзакцию)? –
Вы правы, что лучше всего использовать время жизни контекста как можно короче, но это значит создать его, используя его для * некоторой операции *, а затем избавиться от него, где * некоторая операция * может включать в себя несколько запросов к базе данных , Вы не должны ** создавать новый для каждого вызова базы данных. –