1
votes

Here are the main pillars of my problem:

  • I have implemented a request-response service layer over http. That is a request (object) is sent to server, there it is processed, and then a response is sent to the client (TypeScript/javascript).
  • Both the request object and the response object may contain breeze entities.
  • After receiving the response from the server, if there are also breeze entities contained in the response, I need to update the client cache (entity manager).
  • The controller taking care of the request processing is marked with [BreezeController], so the entities are just like breeze expects them to be. The request and responses are themselves NOT breeze entities.

I tried to find a method somewhere in breeze (entity manager?), where, if I pass a list of entities retrieved from server, these are used to update the local cache, but I did not find any. After studying the source code, I did some changes in the breeze library, where I exposed the MappingContext internal class and did the following (TypeScript code):

public processEntityRequestAsync<TResponse>(request: requestModel.RequestBase): Q.Promise<TResponse> {
  var promise = this.requestProcessor.processRequest<TResponse>(request);
  var processedPromise = promise.then(r => {
    // TODO everything in this method is a hack using internal things from breeze
    // to update the entities after getting them from server
    var updatedEntities = <any[]>(<any>r).UpdatedEntities;
    if (updatedEntities) {
      var dataService = <breeze.DataService>(<any>breeze.DataService).resolve([{
        serviceName: this.manager.dataService.serviceName,
        adapterName: "WebApi",
      }]);
      var mappingContext = new (<any>breeze).MappingContext({
        query: null, // tells visitAndMerge that this is a save instead of a query
        entityManager: this.manager,
        mergeOptions: { mergeStrategy: breeze.MergeStrategy.OverwriteChanges },
        dataService: dataService,
      });

      // Note that the visitAndMerge operation has been optimized so that we do not actually perform a merge if the 
      // the save operation did not actually return the entity - i.e. during OData and Mongo updates and deletes.
      updatedEntities = mappingContext.visitAndMerge(updatedEntities, { nodeType: "root" });
    }
    return r;
  });
  return processedPromise;
}

NOTE: the <any> conversions are used to bypass the Typescript type checking and use breeze internals.

This works, however I do not like that I have to use breeze internals AND that I have to modify the library for this purpose. Is there a better way to achieve my target?

1
I have a similar problem, there's a small section on at the end of [this][breezejs.com/documentation/querying-depth] breeze documentation page which might help. However I tried that approach unsuccessfully because I got some errors with the merging process, but it worth taking a look. - Ariel

1 Answers

0
votes

I'm not entirely sure I understand the question but take a look at the discussion of the JsonResultsAdapter: http://www.breezejs.com/documentation/web-service-data-mapping

The idea is that a JsonResultAdapter can be used on the client to coerce any json data into entities that will be merged into the EntityManager.