Is this possible? Or is the data contained within entities supposed to be copied to other objects in order to be worked with outside the scope of a database transaction?

asked Sep 03 '10 at 11:48

ScottyH's gravatar image


edited Sep 03 '10 at 15:35

Alex%20Yakunin's gravatar image

Alex Yakunin

One Answer:

If you really need to create them outside of a Session, you should transform them to some other objects - either manually, or using our own O2O mapper (btw, O2O mapper can also extract the modifications from produced graph and convert them to our OperationLog object, that allows to apply them to original entities further).

O2O mapper example is currently in development. For now you can study test project for Manual involving it.

But there is another alternative: DisconnectedState type. It is briefly described in Manual; also, it it is used in the following samples:

  • WCF Sample (everywhere)
  • WPF Sample (attached to Session to cache its state w/o hitting DB - i.e. this sample shows its typical usage in client-side code)
  • OrderAccounting project in Sandbox (the same, but in MDI app). I don't recommend you to study it right now, because currently we've already significantly improved this sample. Wait for 7th of September, it should be updatad till that day.

Note that DisconnectedState doesn't allow you to use your entities without a Session - i.e. you anyway need a Domain and Session to use them. But it fully disconnects the Session it is attached to from the underlying storage.

But note that you can always build a client-side Domain relying on memory:// protocol to use sessions with DisconnectedState in client-side application. WCF sample is based on exactly this approach.

DisconnectedState is serializable.

Being compared to regular object graph, DisconnectedState provides the following new features:

  • It knows exactly every object cached by it. It can instantly resolve objects by Keys, enumerate all the objects of particular type (or simply all the objects there), etc.
  • It knows exactly caching state of each field. I.e. it isn'tnecessary to cache values of all the fields there.
  • It is capable of transparently fetching & caching any non-cached object, field or EntitySet<T> using the Session it is attached to.
  • It tracks all the references and backreferences for each cached object. This allows it to populate cached EntitySets instantly, as well as identify the objects referencing the removed one on removal - e.g. to block this attempt because of constraint (see [Association] attribute properties).
  • It efficiently supports local transactions, including nested. Moreover, the cost of rollback there is zero; the cost of commit is proportional to the amount of modifications made in that transaction (i.e. amortized zero as well).
  • Consequently, it's also safe to throw exceptions from your BLL code, when there is DisconnectedState: all the modifications made by top-level transactional method that thrown the exception will be rolled back as well.
  • There is Merge method allowing to merge one DisconnectedState with another.
  • Operation tracking. It records all the activities in one of two logging modes (system operation logging or top-level operation logging) and allows to replay them. Logging is also fully transactional.
  • Object version tracking (optimistic locking support).

DisconnectedState is relatively new feature of DO, so it's one of rapidly evolving (but not well-documented) parts there.

answered Sep 03 '10 at 15:27

Alex%20Yakunin's gravatar image

Alex Yakunin

edited Sep 03 '10 at 15:32

Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA