tags:

views:

465

answers:

1

I want to create "previous versions" so a user can undo changes made and roll back to a previous version.

I've got a manager object with various properties and a collection of managed staff. this relates to two tables in the database with staff linked to the manager by a foreign key.

What i'd like to do is duplicate the manager and all his staff and save it back to the database as a new entry in the manager table and a series of new entries in the staff table that our related to the new manager.

I'm using nhibernate and wondered if there was a clever way of doing it with this.

The only way i can think of doing this is manually:

manager old = getManager(); // get the original for copying 

manager newManager = new manager(); // create a blank object
newManager .name = old.name //give the new manager the old one's props;

//cycle through the staff duplicate and add to new managers staff collection
foreach(staff s in old.staffCollection)
{
  staff newStaff = new staff();
  newstaff.name = s.name;
  newManager.staffCollection.Add(newstaff); 
}

the above example is not exactly how i'd do it but you get the idea i hope.

I've thought about using reflection to get the props instead of manually setting them but that's about as clever as i've got.

is there a way in nhibernate to copy the object graph and persist it back as new entries?

or has anybody got any bright ideas??

A: 

If you mark your Entities as Serializable you could do Binary Serialization.

   public static MemoryStream Serialize(object data)
    {

        MemoryStream streamMemory = new MemoryStream();
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;

        formatter.Serialize(streamMemory, data);

        return streamMemory;
    }
    public static Object Deserialize(MemoryStream stream)
    {

        BinaryFormatter formatter = new BinaryFormatter();
        formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
        return formatter.Deserialize(stream);

    }

Essentially you would call the Serialize then the DeSerialize method this will give you a deep copy of your graph, then you'd have to update any ID's you might have.

Word of caution, I'm not sure how this will play with nHibernates lazy loading functionality. I've done this a lot but not with objects I pull from nHibernate. Also don't forget to put Serializable on your objects.

JoshBerke
I get an errorSystem.Runtime.Serialization.SerializationException : Type 'NHibernate.Cfg.Configuration' in Assembly 'NHibernate, Version=1.2.1.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4' is not marked as serializable.i can't mark that as serializable too?
Charlie Bear
Nope you shouldn't, your objects don't have any reference to that or the Session or SessionFactory do they?
JoshBerke
some static methods do. i have manager.create(newManager) for example. I guess you're gonna tell me i should use a repo pattern and stop ref nhibernate on my entities?
Charlie Bear
Yea I would tell you that:-) But a static method shouldn't do it. Are you using lazy loading? You can try and turn off lazy loading...
JoshBerke
hmm i'm not lazy loading. I think i need to try and find the hidden references...
Charlie Bear
Yep find them and kill them.
JoshBerke