I have another problem to solve:

have this entity:

class Contact
{
  ID
  HistoryID
  Data1
  Data2
}

when i use this:

using (Session.Open(...))
{
  using(var tranScope = GetTransaction())
  {
    var contact = Query<Contact>.Single(...);
    contact.Data2 = "new udpate value";

    tranScope.Complete();
  }
}

in normal way everything is saved to db table. But i want something like that:

lets say have this record in db: table 'Contact' columns (& data) ID HistoryID Data1 Data2


1 NULL value1 value2

when update code above is execute i DONT want this:

ID HistoryID Data1 Data2


1 NULL value1 new udpate value

but want to NOT touch existing row but to create new row with new edited value, table now contains 2 rows after update:

ID HistoryID Data1 Data2


1 NULL value1 value2 2 1 value1 new udpate value

I want to do this naturally without any special function like (UpdateAndClone) which makes this manually, i want to do this by some special interface attached to entity "Contact" or on some SessionBound derivation class, or other interface which allows me to block updates of existing row and to create new "cloned" row. Is something like this possible within DO4 by natural way or must do it manually?

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked Dec 03 '09 at 14:39

Peter%20%C5%A0ulek's gravatar image

Peter Šulek
492313236


One Answer:

In your case I'd do this in more explicit fashion:

  • IVersionizedObject becomes read-only when it gets committed

  • IVersionizedObject.ActiveVersion gets active version by any of its clones

  • IVersionizedObject.GetMutableVersion gets a new mutable clone of it allowing you to modify it.

So any write operations with such object look like this:

var mutable = origin.GetMutableVersion();
  mutable.A = ...;
  mutable.B = ...;
  var active = origin.ActiveVersion;
  Assert.AreTheSame(active, mutable); // Mutable version becomes active

  // Later, but in the same transaction:
  var mutable2 = origin.GetMutableVersion();
  Assert.AreTheSame(mutable, mutable2);

Related issue:

  • http://code.google.com/p/dataobjectsdot ... ail?id=192 - although this must be helpful for such problems, I'm not sure if we really must implement this as described. Such filters can be added e.g. by your own extension methods as well (and this is already possible), and such approach seems easier to understand: IQueryable<iversionizedobject>.WhereActive(true);

Note that to implement this well, you must attach something like VersionValidator to your sessions (this can be done fully automatically via IModule) - a service, that will be responsible for tracking uncommitted versionized objects and allowing them being writeable + ensuring the identity for mutable versions.


Why I recommend this approach:

  • If you try to do this for standard entities as you wanted, you'll break lots of patterns. E.g. in your case entity gets a different key after being modified.

  • Your pattern can be implemented by wrapping (hiding) our own entities into your custom, actually - non-persistent types (that's like much like what we do in our EntitySet<t>). But this is more complex case; moreover, you won't be able to use your type in queries (EntitySet<t> is supported because there is a special code in our LINQ translator for it).

So I recommend you to use the approach I proposed.

Btw, may be it's not a good idea to implement such a "historization" at all: in the worst case only the amount of history will grow up during application lifetime, but not the amount of actual data it deals with. So indexes there will be "flooded" by generally rarely used info.

So what's the actual problem you're going to solve?

answered Dec 03 '09 at 14:59

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

Thanks, i will try your suggestion and let you know my results.

(Dec 03 '09 at 14:59) Peter Šulek Peter%20%C5%A0ulek's gravatar image
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