| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 | using DevExpress.Xpo;using DevExpress.Xpo.Metadata;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Ips.Library.DxpLib{    public class CloneHelper : IDisposable    {        readonly Dictionary<object, object> clonedObjects;        readonly Session targetSession;        public CloneHelper(Session targetSession)        {            clonedObjects = new Dictionary<object, object>();            this.targetSession = targetSession;        }        public T Clone<T>(T source)        {            return Clone<T>(source, false);        }        public T Clone<T>(T source, bool synchronize)        {            return (T)Clone((object)source, synchronize);        }        public object Clone(object source)        {            return Clone(source, false);        }        public object Clone(object source, bool synchronize)        {            if (source == null)                return null;            XPClassInfo targetClassInfo = targetSession.GetClassInfo(source.GetType());            object target = targetClassInfo.CreateNewObject(targetSession);            clonedObjects.Add(source, target);            foreach (XPMemberInfo m in targetClassInfo.PersistentProperties)            {                CloneProperty(m, source, target, synchronize);            }            foreach (XPMemberInfo m in targetClassInfo.CollectionProperties)            {                CloneCollection(m, source, target, synchronize);            }            return target;        }        private void CloneProperty(XPMemberInfo memberInfo, object source, object target, bool synchronize)        {            if (memberInfo is DevExpress.Xpo.Metadata.Helpers.ServiceField || memberInfo.IsKey)            {                return;            }            object clonedValue = null;            if (memberInfo.ReferenceType != null)            {                object value = memberInfo.GetValue(source);                if (value != null)                {                    clonedValue = CloneValue(value, synchronize, false);                }            }            else            {                clonedValue = memberInfo.GetValue(source);            }            memberInfo.SetValue(target, clonedValue);        }        private void CloneCollection(XPMemberInfo memberInfo, object source, object target, bool synchronize)        {            if (memberInfo.IsAssociation && (memberInfo.IsManyToMany || memberInfo.IsAggregated))            {                XPBaseCollection colTarget = (XPBaseCollection)memberInfo.GetValue(target);                XPBaseCollection colSource = (XPBaseCollection)memberInfo.GetValue(source);                foreach (IXPSimpleObject obj in colSource)                {                    colTarget.BaseAdd(CloneValue(obj, synchronize, !memberInfo.IsManyToMany));                }            }        }        private object CloneValue(object propertyValue, bool synchronize, bool cloneAlways)        {            if (clonedObjects.ContainsKey(propertyValue))            {                return clonedObjects[propertyValue];            }            object clonedValue = null;            if (synchronize && !cloneAlways)            {                clonedValue = targetSession.GetObjectByKey(targetSession.GetClassInfo(propertyValue), targetSession.GetKeyValue(propertyValue));            }            if (clonedValue == null)            {                clonedValue = Clone(propertyValue, synchronize);            }            return clonedValue;        }        public void Dispose()        {            if (targetSession != null)                targetSession.Dispose();        }    }}
 |