donderdag 6 oktober 2011

IUpdatable, what is it supposed to do?

I’m setting up an OData service by means of WCF Data Services. The DataContext publishes a list of BloodPressureMeasurements. These are queried from a more generic model in a lower tier, which in turn is persisted somewhere. So in essence I work with a model specific for the service, hence we call it the ServiceModel.

To publish the BPM’s, the DataContext contains a

public IQueryable<BloodPressureMeasurement> BloodPressureMeasurements

and in the get method I take care of the mapping from the generic model to the ServiceModel. That was the relatively easy part.

Now I want to enable adding new BPM’s. For the service to accept that, the DataContext has to implement IUpdatable. I have found several examples using either Entity Framework or LINQ to SQL. In both cases, most of the actual ‘IUpdatable-work’ is offloaded to the underlying techniques. And neither the official documentation nor the examples explain why IUpdatable is even there, and what the implementation should accomplish.

I’ve started implementing it nevertheless, and that made me discover exactly that: what should it do? In essence, when the data has to be updatable, WCF Data  Services needs a place to collect all the changes, whereafter it can ask to save all those changes (or discard them). So the IUpdatable implementation should provide some sort of delta-collection. If you get that, it becomes more clear what each of the methods should do.

And while experimenting with IUpdatable and writing this blog, I finally found a very valuable resource on the Astoria Team Blog (now WCF Data Service Team Blog, why didn’t I look there earlier?) Read, it’s a good explanation.

I chose a very simple solution: two List<BloodPressureMeasurement> variables, one for additions, one for deletions (editing is not permitted in our case). Since BPM objects are small POCO’s, I can send the objects themselves around. If you instead want to move around references to the objects, you have to implement ResetResource and ResolveResource.

Furthermore, there are no master-detail collections to be taken care of, so I could also leave out SetReference, Add- & RemoveReferenceToCollection.

After implementing I discovered one more thing that might be handy to know: If you implement a ChangeInterceptor on your service, I will be called in this sequence:

  1. all the methods on IUpdatable (as implemented by the context) for assembling the delta
  2. your ChangeInterceptor
  3. IUpdatable.SaveChanges

Happy Data Servicing!