Я пытаюсь реализовать шаблоны Repository и UnitOfWork с использованием Entity Framework.
Это сценарий:
Пользователь может добавлять или изменять подробные записи в главном окне подробностей, и при нажатии «сохранить» добавленные / измененные записи отправляются на сервер.
Затем я выполняю CreateOrUpdateMultiple ().
CreateMultiple добавить новые записи в хранилище.
UpdateMultiple извлекает записи, которые будут обновлены.
После завершения двух операций мне нужно обновить основную запись суммой (полем) со всеми подробными записями. (Под всем я имею в виду существующие, которые не были изменены, и те, которые были в памяти)
Это то, что я до сих пор думал ...
Будучи пуристом с шаблоном репозитория, я должен извлечь все подробные записи, а затем смешать в одном списке существующие записи (измененные или нет) и добавленные, а затем выполнить операцию суммирования, но что если поле количества подробных записей является вычисляемым полем базы данных?
Чтение из базы данных только записей, подлежащих обновлению (думая, что это будет быстрее, потому что если у меня будет 40 записей, и только 3 будут изменены, а 2 добавлены, я не буду читать весь набор), а затем как-то выполнить обновление основной записи, но проблема в том, что эти записи еще не в базе данных.
У меня есть только один экземпляр ObjectContext для всех операций, и я вызываю SaveChanges () в моем сервисе для фиксации всего за одну транзакцию.
Что вы мне посоветуете сделать? Или как вы справляетесь с такой ситуацией?
Заранее спасибо
// Update
Здесь более технически описано
Это то, что я имею сейчас, используя транзакции ... и это то, чего я пытаюсь избежать из-за всех обращений к базе данных
//Service Layer
Method()
{
Method1.Invoke(masterRecordId, detaildRecords); //
}
//Business Layer
Method1(masterRecordId, detailRecords)
{
using(TransactionScope ts = new TransactionScope())
{
var recordsToUpdate = dal.RetrieveOnlyRecordsToUpdate();
//Update retrieved records with the values of recods comming from the client
dal.Update(recordsToUpdate); //ctx.ApplyChanges(); and ctx.SaveChanges();
dal.Add(recordsToAdd) //ctx.Add(detail records); and ctx.SaveChanges();
//Update master record TotalSum
dal.UpdateMasterRecord(masterRecordId); //Here is performed ctx.ExecuteStoredCommand("UPDATE MasterTable = SUM() WHERE MasterRecordId = {0}")...
Method2();
ts.Complete();
}
}
Method2(masterRecordId)
{
using(TransactionScope ts = new TransactionScope())
{
MasterRecord m = Retrieve(masteRecordId);
Notification notification = new Notification(){ ...assign properties..., m.TotalSum};
dal.Add(notification); //ctx.Add(notification); and ctx.SaveChanges();
ts.Complete();
}
}
Это то, что я хочу сделать ...
//Service Layer
Method()
{
Method1.Invoke(masterRecordId, detail records);
UnitOfWorkManager.Current.Commit(); //
}
//Business Layer
Metodo1(masterRecordId, detail records)
{
MasterRecord masterRecord = repository.Retrieve(masterRecordId);
var recordsToUpdate = repository.RetrieveOnlyRecordsToUpdate();
//Update retrieved records with the values of recods comming from the client
repository.Modify(recordsToUpdate);
repository.Add(recordsToAdd);
//Here i'm stuck and i'm thinking it should be something like this.
masterRecord.TotalSum = sum(detailRecords in memory + detail records in database); //
repository.Modify(masterRecord); //
or
//Another way somehow...
//Then keep going with the udpated master record
Method2(masterRecord);
}
}
Method2(masterRecord)
{
//Create notification
var notification = new Notification(){ ...properties.., masterRecord.TotalSum};
repository.Add(notification);
}