I am using Nhibernate (I am a complete noob), and what I want to be able to do is copy an entity that is loaded from the database and save it with a new Id... has anyone run into this situation? Any help would be very appreciated.
问题:
回答1:
I need to do exactly this for a very complex set of objects and what I have found so far is:
NHibernate does not exactly support this.
If you try to simply replace the Id of an object you got from a session, you will get an Nhibernate error: identifier of an instance of was altered from <9ae3868d-17bf-4314-ba0c-4eb3b44b1a2e> to <2b2b67c6-a421-48c4-836c-4c27f6481718>
If the session no longer knows about the objects it retrieved, i.e if you evict them before saving and flushing, just changing the ids will now work. So you could write code like this:
public void CloneStudent(Guid studentId)
{
// Get existing student
Student student = _session.Get<Student>(studentId);
// Copy by reference
Student newStudent = student;
// Reset Id to do quick and dirty clone
newStudent.Id = Guid.NewGuid();
newStudent.Sticker = "D";
// Must evict existing object or Nhibernate will throw object modified error
_session.Evict(student);
// Save new object
_session.Save(newStudent);
_session.Flush();
}
The problem with this is if your object graph has any depth you have to be sure to evict the entire set, and then you may need the originals in the session still you have to retrieve them again. This is a logistical headache and yields code with very obscure and convoluted intentions.
I do not recommend.
What is more commonly done is serialize to a binary stream and reconstitute this stream into a new set of objects. Fine, but only works if your objects are all serializable.
That is not the case for me, what I am doing is I wrote manual code to make deep copies of an object graph using copy constructors. This is complex and also can lead to maintenance issues, but if the objects cannot be serialized there are few better alternatives.
Sorry, deep copying objects remains a complicated task if serialization is not an option.
回答2:
Just do new MyClass()
and copy everything except the Id. You can use reflection for that.