存储库 +工作单元当详细记录发生更改时,EF 更新主记录。 (总金额=总和(金额))
我正在尝试使用实体框架实现存储库和工作单元模式。
这是这样的场景:
用户可以在主从窗口中添加或修改详细记录,当点击“保存”时,添加/修改的记录将发送到服务器。
然后我执行 CreateOrUpdateMultiple()。 CreateMultiple 将新记录添加到存储库。 UpdateMultiple 检索将要更新的记录。
两个操作完成后,我需要使用包含所有详细记录的总和(字段)更新主记录。 (我的意思是未修改的现有记录和内存中的记录)
这就是我到目前为止的想法...
作为存储库模式的纯粹主义者,我应该检索所有详细记录,然后应该混合在一个列表中现有记录(修改或未修改)和添加的记录,然后进行求和操作,但是如果详细记录的金额字段是数据库计算字段怎么办?
仅从数据库中读取要更新的记录(认为这会更快,因为如果我有 40 条记录,只有 3 条被修改,2 条被添加,我将不会读取整个集合),然后以某种方式执行对主记录的更新,但问题是这些记录尚未在数据库中。
我只有一个 ObjectContext 实例用于所有操作,并且我在服务中调用 SaveChanges() 以在一个事务中提交所有操作。
你建议我做什么?或者你如何实现这种情况?
预先感谢
//更新
这里更技术性地描述
这就是我现在使用 transactionScope 所拥有的...这是我试图避免的,因为所有对数据库的调用
//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);
}
i'm trying to implement a Repository and UnitOfWork patterns using Entity Framework.
This is the scenario:
An user can add or modify detail records in a master-detail window and when hit "save" the added/modified records are sent to the server.
Then i perform a CreateOrUpdateMultiple().
CreateMultiple add the new records to the repository.
UpdateMultiple retrieve records that going to be updated.
After the two operations completes i need to update the master record with a sum(field) with all detail records. (With all i mean the existing ones that were not modified and the ones in memory)
This is what i have thought so far...
Being purist with repository pattern i should retrieve all detail records and then should mix in one list the existing records (modified or not) and the addded ones, and then do the sum operation, but what if the amount field of detail records is a database calculated field?
Read from database only records to be updated (thinking this will be faster because if i have 40 records and just 3 are modified and 2 added i will not read the entire set) and then somehow perform the update to the master record, but the problem is those records aren't yet in the database.
I have just one ObjectContext instance for all operations and i call SaveChanges() in my service to commit all in just one transaction.
What do you advice me to do? Or how do you archieve this kind of situation?
Thanks in advance
//Update
Here more technically described
The is what i have right now using transactionScope... and this is what i'm trying to avoid because of all the calls to database
//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();
}
}
This is what i want to do...
//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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您想将其作为事务执行,并且仅调用
SaveChanges
一次,则必须在调用SaveChanges
之前在应用程序中执行此操作。因此,通常在进行任何更改之前必须获取总和,并通过更新值、插入值和删除值修改总和。然后您将新的总和值设置到主记录中。如果你这样做,你就会有工作单元。为什么其他方法不太好。
If you want to do it as transaction and call
SaveChanges
only once you must do it in your application beforeSaveChanges
is called. So generally you must get sum before you do any change and modify the sum by updated values, inserted values and deleted values. Then you will set the new sum value into the master record. If you do it this way you will have unit of work.Why other approaches are not so good.