[英]How to deep copy master detail collection dynamically in silverlight C#
我想创建一个动态方法,该方法将深度复制实体(实体可能包含复杂类型)。 和往常一样,像c#.net。 我已经在C#中尝试过,然后系统正常工作。 但是,当我想在Silverlight中进行深度复制时,系统会向我发送错误消息(找不到Silverlight的属性设置方法)。 注意:然后,我看到了C#和Silverlight之间非常细心的区别。 我发现一个区别是-属性'write'为假。 在这种情况下,我该怎么办? 代码示例:
[Serializable]
public class Department
{ [Key]
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public int EmployeeId { get; set; }
}
[Serializable]
public class Employee
{
[Key]
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
[Include]
[Composition]
[Association("DC_Receive_Department", "EmployeeId", "EmployeeId")]
private List<Department> _DepartmentList = new List<Department>();
public List<Department> DepartmentList
{
get { return _DepartmentList; }
set { _DepartmentList = value; }
}
}
public static class DictionaryExt
{
public static T MyDeepCopy<T>(this T source)
{
try
{
//Throw if passed object has nothing
if (source == null) { throw new Exception("Null Object cannot be cloned"); }
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
//variable declaration
T copy;
var obj = new DataContractSerializer(typeof(T));
using (var memStream = new MemoryStream())
{
obj.WriteObject(memStream, source);
memStream.Seek(0, SeekOrigin.Begin);
copy = (T)obj.ReadObject(memStream);
}
return copy;
}
catch (Exception)
{
throw;
}
}
public static ObservableCollection<T> DeepCopyMasterDetail<T>(this ObservableCollection<T> entityCollection)
{
try
{
Type t = entityCollection.GetType();
ObservableCollection<T> RooTList = new ObservableCollection<T>();
foreach (T objEntity in entityCollection)
{
//var separateMaster = objEntity.MyDeepCopy();
//RooTList.Add(separateMaster);
T iObject = CreateMaster(objEntity);
RooTList.Add(iObject);
}
return RooTList;
}
catch (Exception ex)
{
throw ex;
}
}
private static dynamic CreateMaster<T>(this T objSource)
{
//Get the type of source object and create a new instance of that type
Type typeSource = objSource.GetType();
object objTarget = Activator.CreateInstance(typeSource);
//Get all the properties of source object type
PropertyInfo[] propertyInfo = typeSource.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
objTarget = objSource.MyDeepCopy();
//Assign all source property to taget object 's properties
foreach (PropertyInfo property in propertyInfo)
{
//Check whether property can be written to
//if (property.CanWrite)
//{
//check whether property type is value type, enum or string type
if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection<>))
{
Type t1 = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
dynamic safeValue1 = (property.GetValue(objSource, null) == null) ? null : Convert.ChangeType(property.GetValue(objSource, null), t1, null);
object list = null;
foreach (dynamic item in safeValue1)
{
if (list == null)
{
list = BuildListHelper(item);
}
((dynamic)list).Add(CreateMaster(item));
}
if (list != null)
{
property.SetValue(objTarget, list, null);
}
}
}
return objTarget;
}
public static ObservableCollection<T> BuildListHelper<T>(this T item)
{
ObservableCollection<T> list = new ObservableCollection<T>();
return list;
}
}
private static T BaseDeepCopy<T>(this T source)
{
try
{
//Throw if passed object has nothing
if (source == null) { throw new Exception("Null Object cannot be cloned"); }
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
//variable declaration
T copy;
var obj = new DataContractSerializer(typeof(T));
using (var memStream = new MemoryStream())
{
obj.WriteObject(memStream, source);
memStream.Seek(0, SeekOrigin.Begin);
copy = (T)obj.ReadObject(memStream);
}
return copy;
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// This method used to deep copy of a collection
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entityCollection"></param>
/// <returns></returns>
public static ObservableCollection<T> DeepCopy<T>(this ObservableCollection<T> entityCollection)
{
try
{
Type t = entityCollection.GetType();
ObservableCollection<T> RooTList = new ObservableCollection<T>();
foreach (T objEntity in entityCollection)
{
T iObject = DeepCopy(objEntity);
RooTList.Add(iObject);
}
return RooTList;
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// this method used to create deep copy of any Entity
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="objSource"></param>
/// <returns></returns>
public static T DeepCopy<T>(this T objSource)
{
try
{
//Get the type of source object
Type typeSource = objSource.GetType();
// create a new instance of that type by deep copy
T objTarget = objSource.BaseDeepCopy();
//Get all the properties of source object type
List<PropertyInfo> propertyInfo = typeSource.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(m => m.PropertyType.IsGenericType && m.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection<>)).ToList();
//Assign all source property to taget object 's properties
foreach (PropertyInfo property in propertyInfo)
{
Type t1 = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
dynamic safeValue1 = (property.GetValue(objSource, null) == null) ? null : Convert.ChangeType(property.GetValue(objSource, null), t1, null);
dynamic dcoll = property.GetValue(objTarget, null);
foreach (dynamic child in safeValue1)
{
dcoll.Add(DeepCopy(child));
}
}
return objTarget;
}
catch (Exception ex)
{
throw ex;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.