相关:Set Properties that not null using linq and reflection
嗨专家
我更改了上面链接中的代码:
public static void MyCopy<T>(this T src, T dest)
{
var notNullProps = typeof(T).GetProperties()
.Where(x => x.GetValue(src, null) != null);
foreach (var p in notNullProps)
{
p.SetValue(dest, p.GetValue(src, null),null);
}
}
我写了这段代码来复制peroperties:
NorthwindModel1.Order ord1 = new NorthwindModel1.Order() {CustomerID="Nima",Freight=1.33m,ShipCity="Agha" };
NorthwindModel1.Order ord2 = new NorthwindModel1.Order() ;
ord1.MyCopy(ord2);
但是我收到了这个错误:
EntityReference已经初始化。 InitializeRelatedReference仅应用于在实体对象的反序列化期间初始化新的EntityReference。
请帮我解决这个问题
答案 0 :(得分:3)
正如评论中所提到的,你的反思代码不是问题,而是(正如异常消息明确告诉的那样)你间接触发了一个实体引用的重置。我的建议是双重的:要么修改你的反射代码只能复制标量属性(字符串,日期等等) - 或者忽略引用和集合 - 或者使用序列化:
public static T CloneBySerialization<T>(this T source) where T : EntityObject {
var serializer = new DataContractSerializer(typeof(T));
using (var ios = new MemoryStream()) {
serializer.WriteObject(ios, source);
ios.Seek(0, SeekOrigin.Begin);
return ((T) serializer.ReadObject(ios));
}
}
我必须警告你,通过这种方法,你将得到完整的对象图或引用。如果克隆的对象是实体,您将无法使用它/将其附加到另一个上下文,因为引用和外键也已被复制,“逐字”,这一切都可能导致冲突。如果您在密钥中使用标识列,问题会变得更糟。
我在以前关于这些问题的工作中做了很多魔术,就克隆而言,上面的代码就是你所需要的。全部,真的。
但是,要修复上下文问题和克隆实体的可用性,您必须清除引用,并假设您还在使用“root”实体¹↔*方向关系图(我希望我远程清楚,因为故事很长)以下也是必要的。
public static void ClearReferences(this EntityObject entity) {
if (entity == null)
return;
foreach (var p in entity.GetType().GetProperties()) {
if (p.PropertyType.IsGenericType) {
var propertyType = p.PropertyType.GetGenericTypeDefinition();
if (propertyType == typeof(EntityReference<>)) {
var reference = p.GetValue(entity) as dynamic;
if (reference.EntityKey != null) {
reference.EntityKey = null;
((EntityObject) reference.Value).ClearReferences();
}
}
if (propertyType == typeof(EntityCollection<>)) {
var children = (p.GetValue(entity) as IEnumerable<EntityObject>).ToList(); // covariance
foreach (var child in children)
child.ClearReferences();
}
}
}
}
所以我的想法是你首先克隆(通过序列化/反序列化),然后你“净化”。