One of the issues that keeps cropping up is LINQ for SQLs support for nTier scenarios and having to reattach the object to the DataContext.
However this problem is exhibited by all ORMs in nTier scenarios ( though not in web sites) and you basically have 2 choices
- refetch the object from cache/DB and replay all changes to see what has changed then you can craft a custom Update to just change the items changed.
- update all fields in the DB.
While the 2nd method is easier the first is more efficient especially when you consider that it is very likely that the object is still in a cache.
In both cases a row version/timestamp is normally required for concurrency .
ProcessOrder ( Order order)
{
var orderDB = ThreadDataContext.Context; //get dataContext
//Products is the table we draged and dropped in the dbml designer
var _oldOrder = (from _orders in order.Orders
select _order where _order.id = order.id).Single();
//note as you have the old order and new order you can apply some logic , this is much more efficient than doing it in a db
if ( _oldOrder.IsFinalized())
throw new InvalidOperationException("Finalized order cant be changed");
if ( _OldOrder.RowVer != _order.RowVer)
throw new ConcurrencyException("Order already Changed") ;
//update the fields
_oldOrder .Number = order.Number;
_oldOrder .CustomerId = order.CustomerId;
// etc ...
new BLL.OrderProcessor().Process(_oldOrder); //process
}
You could use reflection to automate the copying and then the new order would just overwrite the previous order but this has 2 issues
- It would be slow
- It would allow the client to trash the servers object by serializing on top of it .
It is also worth noting for medium and large services you are likely to have an internal object module and code to convert from messages to internal code anyway ( see OO with services article)
I think fetching the old order is good business practice anyway and stops issues like a client bug updatting a service and trashing a fulfilled order with a new one . Fetching the old order allows you to uphold one of the SOA tennats/rules that a service should never trust a client .
It is worth noting the same thing needs to be done for member objects or collections and hence its usefull to provide some simple converter classes for each type . The result of this is that services ( that write to a DB) using an ORM tend to have an external message structure different from the internal OO representation even when the OO model and service is quite small. Even though this is a burden it does not introduce a lot of time or any complexity and is a good practice to follow for all but the smallest services anyway. ( Again see OO with services article)
Print | posted on Wednesday, January 14, 2009 11:00 PM