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();
- }
- }
- }
|