存储库+ UnitOfWork + EF更新详细记录时更新主记录。 (TotalAmount =总和(金额))

时间:2011-03-13 08:12:16

标签: entity-framework-4 repository-pattern unit-of-work

我正在尝试使用Entity Framework实现Repository和UnitOfWork模式。

这是情景:

用户可以在主 - 详细信息窗口中添加或修改详细记录,当点击“保存”时,添加/修改的记录将被发送到服务器。

然后我执行CreateOrUpdateMultiple()。 CreateMultiple将新记录添加到存储库。 UpdateMultiple检索要更新的记录。

两次操作完成后,我需要使用包含所有详细记录的sum(字段)更新主记录。 (我的意思是现有的未修改的和内存中的那些)

这是我到目前为止所想的......

  1. 使用存储库模式纯粹我应该检索所有详细记录,然后应该在一个列表中混合现有记录(已修改或未添加)和添加的记录,然后进行求和操作,但是如果金额字段怎么办?详细记录是数据库计算字段吗?

  2. 只从数据库中读取要更新的记录(认为这会更快,因为如果我有40条记录,只有3条被修改,2条添加我将无法读取整套)然后以某种方式执行主记录的更新,但问题是那些记录尚未存在于数据库中。

  3. 我只有一个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);
    }
    

1 个答案:

答案 0 :(得分:0)

如果您想将其作为交易进行操作,只有在调用SaveChanges之前必须在应用程序中执行此操作时才调用SaveChanges。因此,通常您必须在进行任何更改之前获得总和,并通过更新的值,插入的值和已删除的值修改总和。然后,您将新的总和值设置为主记录。如果你这样做,你就会有工作单位。

为什么其他方法不太好。

  • 数据库中的计算字段。这将需要在保存操作后手动重新加载主实体,因为保存详细信息无法重新加载其他实体中的更改。此外,数据库逻辑可能需要触发详细信息表来修改主表中的和。
  • 保存对细节的更改后更新主记录会中断工作单元。