我想做的事情如下:
MyObject myObj = GetMyObj(); // Create and fill a new object
MyObject newObj = myObj.Clone();
Run Code Online (Sandbox Code Playgroud)
然后更改未在原始对象中反映的新对象.
我不经常需要这个功能,所以当有必要的时候,我已经使用了创建一个新对象然后单独复制每个属性,但它总是让我觉得有更好或更优雅的处理方式情况.
如何克隆或深度复制对象,以便可以修改克隆对象而不会在原始对象中反映任何更改?
我在这里找到了这个片段:
public static T DeepClone<T>(this T obj)
{
using (var ms = new MemoryStream()) {
var bf = new BinaryFormatter();
bf.Serialize(ms, obj);
ms.Position = 0;
return (T)bf.Deserialize(ms);
}
}
Run Code Online (Sandbox Code Playgroud)
这说明我们可以通过这个东西对所有相关对象进行深层复制.
我正在尝试这样的副本:
db.Detach(myEntity);
myEntity.EntityKEy = null;
Entity newEntity = new Entity();
newEntity = DeepClone<Entity>(Entity);
db.Entities.AddObject(newEntity);
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
它可以工作,但仍然不会复制任何嵌套的\相关记录.我在这做错了什么?
我有这个结构Entity-> ChildEntity - > ChildChildEntity
- > - one-to-many
所以我假设当我复制实体时它也会复制所有子记录.
更新: 建议之后,我这样做了:
Entity newEntity = new Entity();
Eneity Entity = db.Include("ChildEntity").Where(p=>p.Id==Id).Single();
newEntity = DeepClone<Entity>(Entity);
db.Detach(myEntity);
myEntity.EntityKEy = null;
db.Entities.AddObject(newEntity);
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
在AddObject行上获取异常:
ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象.
我有一个窗口作为WPF应用程序中的对话框.该对话框有一个"确定"和一个"取消"按钮.我将Window的DataContext设置为我的应用程序中的对象实例.用户可以在Window中更改对象属性的值.如果用户单击"取消",我想将属性值恢复为原始值.在WPF中有一种简单的方法吗?
例如,我知道RIA数据服务有RejectChanges.在WPF的客户端是否有类似的东西?
谢谢!
我很惊讶在C#中复制集合对象是多么麻烦,特别是如果你想要一个深层复制.有没有一个很好的设计理由为什么.Net没有采用Java clone()路由,是否有一些我在C#/ .Net中错过的等效范例?