Quantcast
Channel: WCF Data Services forum
Viewing all articles
Browse latest Browse all 877

SaveChanges AND call Action in the same transaction

$
0
0

Hello, gentlemen.

After some digging into the source code I found that it seems to be impossible to pass batch changes AND execute an Action in the same HTTP REQUEST.

It is very frustrating, it was the very first scenario I started with when making feasibility study on WCF DS. Did no one asked you for such a feature?


The scenario:

In business domain, there is OrderHead aggregating OrderLines. In a WPF form user edits Order Head details AND make any changes to Order Lines (in editable grid, including add/delete lines). After that, user clicks button "Confirm Order", server runs huge amount of logic over the CHANGED order+lines data.

For that scenario, on server I would expect to create an Action "Confirm" with the OrderHead as first parameter. And there, I would expect that all the user changes in the OrderHead AND in all its Lines are already in EF ObjectContext, and I would prefer doing all this work in single transaction, single unit of work.

Question: What did you guys think about how such a scenario should be realized.

Another question: Can anyone tell me why in the code below (BatchSaveResult.GenerateBatchRequest()) there a switch: either Queries or ChangedEntries, but NOT BOTH? What is the logic behind?

private ODataRequestMessageWrapper GenerateBatchRequest()
    {
      if (this.ChangedEntries.Count == 0 && this.Queries == null)
      {
        this.SetCompleted();
        return (ODataRequestMessageWrapper) null;
      }
      else
      {
        ODataRequestMessageWrapper batchRequest = this.CreateBatchRequest();
        using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(batchRequest, this.RequestInfo))
        {
          ODataUtils.SetHeadersForPayload(messageWriter, ODataPayloadKind.Batch);
          batchRequest.FireSendingRequest2((Descriptor) null);
          this.batchWriter = messageWriter.CreateODataBatchWriter();
          this.batchWriter.WriteStartBatch();
          if (this.Queries != null)
          {
            for (int index = 0; index < this.Queries.Length; ++index)
            {
              ODataRequestMessageWrapper requestMessage = this.CreateRequestMessage(this.RequestInfo.BaseUriResolver.CreateAbsoluteUriIfNeeded(this.Queries[index].QueryComponents(this.RequestInfo.MaxProtocolVersion).Uri), "GET");
              Version version = this.Queries[index].QueryComponents(this.RequestInfo.MaxProtocolVersion).Version;
              WebUtil.SetOperationVersionHeaders(requestMessage, version, this.RequestInfo.MaxProtocolVersionAsVersion);
              requestMessage.FireSendingRequest2((Descriptor) null);
            }
          }
          else if (0 < this.ChangedEntries.Count)
          {
            this.batchWriter.WriteStartChangeset();
            ClientEdmModel model = ClientEdmModel.GetModel(this.RequestInfo.MaxProtocolVersion);
            for (int index = 0; index < this.ChangedEntries.Count; ++index)
            {
              Descriptor descriptor = this.ChangedEntries[index];
              if (!descriptor.ContentGeneratedForSave)
              {
                EntityDescriptor entityDescriptor = descriptor as EntityDescriptor;
                if (descriptor.DescriptorKind == DescriptorKind.Entity)
                {
                  if (entityDescriptor.State == EntityStates.Added)
                  {
                    if (ClientTypeUtil.GetClientTypeAnnotation((IEdmModel) model, model.GetOrCreateEdmType(entityDescriptor.Entity.GetType())).IsMediaLinkEntry || entityDescriptor.IsMediaLinkEntry)
                      throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BatchNotSupportedForMediaLink);
                  }
                  else if ((entityDescriptor.State == EntityStates.Unchanged || entityDescriptor.State == EntityStates.Modified) && entityDescriptor.SaveStream != null)
                    throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BatchNotSupportedForMediaLink);
                }
                else if (descriptor.DescriptorKind == DescriptorKind.NamedStream)
                  throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BatchNotSupportedForNamedStreams);
                ODataRequestMessageWrapper requestMessage = descriptor.DescriptorKind != DescriptorKind.Entity ? this.CreateRequest((LinkDescriptor) descriptor) : this.CreateRequest(entityDescriptor);
                requestMessage.FireSendingRequest2(descriptor);
                this.CreateChangeData(index, requestMessage);
              }
            }
            this.batchWriter.WriteEndChangeset();
          }
          this.batchWriter.WriteEndBatch();
          this.batchWriter.Flush();
        }
        return batchRequest;
      }
    }





Roman Koreshkov, systems architect


Viewing all articles
Browse latest Browse all 877

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>