How do you perform service-oriented parent-child transactions?

asp.net-web-api breeze entity-framework graphdiff web-services

Accepted Answer

I work with Breeze, and I believe that change tracking on the client is the best course of action. Stateless servers, less traffic between the client and server, and offline use are all made possible via change tracking on the client.

Each entity in Breeze has a "ObjectState" called the EntityAspect, but it is not a component of the domain model. EntityAspects are not required for server-side entities, but the server-side service must understand how to manage client-provided entity state data.

In essence, the service must build, update, or remove entities in accordance with the data received from the client. You can create your own server-side backend for Breeze, but there are already ones that do all of this (in .NET (EF and NHibernate), Java, PHP, Node, and Ruby). Your server merely needs to understand how to communicate with the client.

Imagine that we've modified aSalesOrder and added a newSalesOrderItem . The save package that the Breeze client delivers appears something like this:

{
"entities": [
    {
        "Id": 123,
        "Title": "My Updated Title",
        "OrderDate": "2014-08-03T07:00:00.000Z",
        "entityAspect": {
            "entityTypeName": "SalesOrder:#My.DomainModel",
            "entityState": "Modified",
            "originalValuesMap": {
                "Title": "My Original Title"
            },
            "autoGeneratedKey": {
                "propertyName": "Id",
                "autoGeneratedKeyType": "Identity"
            }
        }
    },
    {
        "Id": -1,
        "SalesOrderId": 123,
        "ProductId": 456,
        "Quantity": 11,
        "entityAspect": {
            "entityTypeName": "SalesOrderItem:#My.DomainModel",
            "entityState": "Added",
            "originalValuesMap": {
            },
            "autoGeneratedKey": {
                "propertyName": "Id",
                "autoGeneratedKeyType": "Identity"
            }
        }
    }
]
}

The SalesOrder with ID# 123 has been changed in this instance (its Title has been changed). TheentityAspect contains theoriginalValuesMap in which the preceding Title is displayed.
The current SalesOrder would need to be updated by the server with the new value. Whether the server needs to query the existing SalesOrder from the database before applying the changes is implementation-dependent.

There has been a new SalesOrderItem added. On the client, a temporary Id named -1 was made for it. A new SalesOrderItem must be created by the server, saved, and given a valid Id.

The created and modified entities as well as KeyMapping information indicating which server-generated keys correspond to the temporary client-side keys should be included in the server's response so that the client can replace them can be found there.

Breeze aims to take care of the challenging aspects for you because change tracking is not an easy task.

2
8/21/2014 9:35:13 PM

Popular Answer

I'd like to add to Steve's response.

To be explicit, it is the developer's responsibility to implement the Order-graph (also known as "Order aggregation") transaction in a relational data model. You must make it work with BreezeJS (and Breeze helpers for.NET servers), though.

In order for this to function, all changes to any entity within the aggregate must take into account the Order, which serves as the aggregate's primary element. If an OrderItem is added, removed, or changed, Make sure you alter the Order concurrently.

How? By increasing the concurrency attribute of the Order (for example, therowVersion (and ensuring Breeze IS AWARE that this is your concurrency property.

You must implement root entity optimistic concurrency if you want to ensure Order aggregate consistency.

Now you have the ability to identify any modifications that have been made to the Order aggregate. That could involve altering the Order or adding, modifying, or deleting one of its OrderItems.

When you save a modified Order aggregate, not all OrderItems must be included in the change-set. Only the OrderItems that have been added, updated, or removed need to be included.

Of course, before you save your adjustment, another user may modify the Order aggregate. Your attempt to save it will be unsuccessful and result in an optimistic concurrency error.

Make sure the client clears the Order and all of its OrderItems from cache after identifying an optimistic concurrency error for an Order, and then re-fetch the aggregate. Re-fetching the root Order entity and fiddling with its items is not a good idea. Make careful to clear the aggregate in its entirety from cache before re-requesting it (the order and its items).

Everyone will be in good shape on the server if they adhere to this protocol.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow