I've posted this before, and I don't mean to show up another's work, however I wanted to add the graph clone impl I use:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using SD.LLBLGen.Pro.ORMSupportClasses;
namespace NS
{
/// <summary>
/// For cloning an Entity and all related entities, ie the whole graph
/// </summary>
public class CloneHelper
{
private CloneHelper()
{
}
private static object CloneObject(object o)
{
object oOut;
lock (o)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
bf.Serialize(ms, o);
ms.Seek(0, SeekOrigin.Begin);
oOut = bf.Deserialize(ms);
ms.Close();
}
return oOut;
}
private static void ResetEntityAsNew(IEntity Entity)
{
Entity.IsNew = true;
Entity.IsDirty = true;
Entity.Fields.IsDirty = true;
for (int f = 0; f < Entity.Fields.Count; f++)
{
Entity.Fields[f].IsChanged = true;
}
}
public static IEntity CloneEntity(IEntity Entity, bool ResetAsNew)
{
IEntity newEntity;
newEntity = (IEntity)CloneObject(Entity);
ObjectGraphUtils ogu = new ObjectGraphUtils();
List<IEntity> flatList = ogu.ProduceTopologyOrderedList(newEntity);
if (ResetAsNew)
for (int f = 0; f < flatList.Count; f++)
ResetEntityAsNew(flatList[f]);
return newEntity;
}
public static IEntity CloneEntity(IEntity Entity)
{
return CloneEntity(Entity, true);
}
public static T CloneEntity2<T>(T Entity)
where T : EntityBase
{
return (T)CloneEntity(Entity, true);
}
public static T CloneEntity2<T>(T Entity, bool ResetAsNew)
where T : EntityBase
{
return (T)CloneEntity(Entity, ResetAsNew);
}
}
}