Reputation: 653
how can I best copy an entity instance in fluent nhibernate 3.3.1; I read an object out of the database, I got an object, now I change some values of this object. This object with little changes want I save.
I have tried to set the Id to 0, this is not working, also I write a Clone method in my Entityclass. Here is my approach.
public class Entity: ICloneable
{
public virtual int Id { get; protected set; }
object ICloneable.Clone()
{
return this.Clone();
}
public virtual Entity Clone()
{
return (Entity)this.MemberwiseClone();
}
}
Do you some tips for me.
Upvotes: 3
Views: 4514
Reputation: 4726
You need to
The clone method is as follows
/// <summary>
/// Clone an object without any references of nhibernate
/// </summary>
public static object Copy<T>(this object obj)
{
var isNotSerializable = !typeof(T).IsSerializable;
if (isNotSerializable)
throw new ArgumentException("The type must be serializable.", "source");
var sourceIsNull = ReferenceEquals(obj, null);
if (sourceIsNull)
return default(T);
var formatter = new BinaryFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, obj);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
To use it you call it as follows
object main;
var copy = main.Copy<object>();
To see some other opinions on what to use, you can view this link aswell Copy object to object (with Automapper ?)
Upvotes: 1
Reputation: 4941
If your objects are not serializable and you are just looking for a quick one-to-one copy of them, you can do this pretty easily with AutoMapper:
// define a one-to-one map
// .ForMember(x => x.ID, x => x.Ignore()) will copy the object, but reset the ID
AutoMapper.Mapper.CreateMap<MyObject, MyObject>().ForMember(x => x.ID, x => x.Ignore());
And then when you copy method:
// perform the copy
var copy = AutoMapper.Mapper.Map<MyObject, MyObject>(original);
/* make copy updates here */
// evicts everything from the current NHibernate session
mySession.Clear();
// saves the entity
mySession.Save(copy); // mySession.Merge(copy); can also work, depending on the situation
I chose this approach for my own project because I have a lot of relationships with some weird requirements surrounding record duplication, and I felt this gave me a little more control over it. Of course the actual implementation in my project varies a bit, but the basic structure pretty much follows the above pattern.
Just remember, that the Mapper.CreateMap<TSource, TDestination>()
creates a static map in memory, so it only needs to be defined once. Calling CreateMap
again for the same TSource
and TDestination
will override a map if it's already defined. Similarly, calling Mapper.Reset()
will clear all of the maps.
Upvotes: 2