LA.NET [EN]

Nov 04

In the previous post, we’ve started looking at identity and how it’s supported by the DataContext component. Today we’ll improve the initial algorithm so that we’re able to support more advanced scenarios.

Even though the first algorithm for identity management was really simple, it ended up showing that identity management ends up adding (at least) two important problems:

  • how to generate new identities;
  • how to distinguish new entities from existing ones and how to distinguish different types of entities.

One possible solution for these problems relies on adding some sort of metadata to our objects. Going back to our initial example, we’ll start by adding an internal __meta object which will hold two important pieces of data:

  • the type of object;
  • the identity of that object;

Notice that the identity of the object must be enough for identifying that object (even amongst objects of different “types”). Another important detail to keep in mind is that we need some way to identify the current type of an object (if we were using a strongly typed language, this wouldn’t be necessary, but with dynamic languages, it’s something that must also be tracked). It’s also important to understand that the objects that will be passed to the trackData method should have this info correctly filled up (unlike objects which will be inserted, where the metadata is supposed to be generated by the identity methods):

var people = [
    { id: 1, name: "luis", address: "fx", 
__meta: { set:
"people", id: "people$1"} },{ id: 2,name: "john", address: "fx",
__meta: { set:
"people", id: "people$2"} }, { id: 3, name: "peter", address: "fx",
__meta: { set:
"people", id: "people$3"} } ];

There’s not much we can say about the previous snippet. It represents a collection of person instances which have their __meta properties set up. Notice that from now on, the identity of each of these objects is given by the __meta.id value (instead of relying in the id field of the object).

Our implementation of the identity related methods need to handle more details. Due to that, I’ve decided to create a helper object which encapsulates all the work needed for getting and creating new identities:

var entityManager = {
  metaCounter: {},
  getEntityId: function (dataContext, entity) {
    return entity.__meta && entity.__meta.id ?
           entity.__meta.id :
           null;
  },
  getNewIdentity: function (dataContext, entity, entitySet) {
    if (!entitySet) {
      Error.invalidOperation("entity set must be defined");
    }
    var _this =entityManager;
    function createMetaInfo(entity, entitySet) {
      var generatedId = _this.metaCounter[entitySet] =
        _this.metaCounter[entitySet] !== undefined ?
            _this.metaCounter[entitySet] + 1 : 0;
      return {
        set: entitySet,
        id: entitySet + "$new:" + generatedId
      };
    }
    if (!(entity.__meta && _entity.__meta.id)) {
      entity.__meta = createMetaInfo(entity, entitySet);
    }
    return entity.__meta.id;
  }
};

A couple of observations regarding the previous helper:

  • the identity of an item relies on the __meta.id property. As you can see, identity relies on concatenating IDs with the type of the current object;
  • new identities must be different from those that belong to objects which have already been persisted (probably in a db on the server side). That’s why new identity use the $new instead of using only $ (I think this is easy to handle on the server side);
  • I’ve introduced the metaCounter object so that we can reuse this object for allowing the insertion of different types of objects.

Now, we can start adding several kinds of objects without any problem. For instance, take a look at the following code:

ctx.insertEntity({ name: "joseph", address: "fx" }, 
"people"); ctx.insertEntity({ name: "joseph", address: "fx" },
"people"); ctx.insertEntity({ value: 1, contact: "123123123" },
"contacts");

And the next image shows the final result:

betteralgorithm

As you can see, with this approach we no longer set the id property of a new person object (that will be done by the server side, when it process an eventual commit performed by the DataContext instance).

Notice that until now we’ve seen the client code needed for supporting addition of new items. A complete solution would still need more work in the server side in order to ensure that items are correctly persisted. On the next post, we’ll start looking at links between objects. Stay tuned for more on MS AJAX.

3 comments so far

  1. william apken
    11:51 am - 11-4-2009

    Thank you Luis,

    You are the only person generating new material on MS Ajax. I think this is truly the way to go on generating a new approach to the web experience.

    Enjoyed your dataContext information a lot. I use the AdoNetDataContext. It is very sweet. Are you going to cover that object?

    I”m trying to generate code to eliminate postbacks. Or at least reduce the number down to a fraction of the original number.

    Is MS Ajax going to continue to be supported 5 years from now?

    Why such a small following?

  2. luisabreu
    12:28 pm - 11-4-2009

    AdoNetDataContext: yes, I will…in fact, the current posts will go in that direction (the adonetdatacontext adds the functions I”m using for identity – and a few more). However, there are still a couple of posts before entering through the ado.net data context object.

    MS AJAX in 5 years: I don”t work at/for MS, but I think that it will be supported

    small following: need to understand that MS AJAX 1.0 wasn”t really geared torwards the web developer that needs JS framework for helping in interacting with the DOM (JQuery is much better there!). However, I think we”ll see an increase in use when MS AJAX 4.0 is out…

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>