在NHibernate更新上实现实体复制

在NHibernate更新上实现实体复制,nhibernate,versioning,Nhibernate,Versioning,我如何在NHibernate做出这样的行为: 在我的域中有一个名为User的实体 // I ommit mapping attributes public class User { int Id {get; set;} int pId {get; set;} //....other props, such as Login, Name, email... } 更新时,我需要将其完整复制。pId必须设置为原始Id。旧实体必须保持不变 所以这一定像一些版本控制系统,其中pId是不可变的

我如何在NHibernate做出这样的行为:

在我的域中有一个名为User的实体

// I ommit mapping attributes
public class User
{
  int Id {get; set;}
  int pId {get; set;}
  //....other props, such as Login, Name, email...
}
更新时,我需要将其完整复制。pId必须设置为原始Id。旧实体必须保持不变


所以这一定像一些版本控制系统,其中pId是不可变的标识,Id是版本。我尝试使用版本映射属性,但它只更新版本字段,而不重新创建完整的实体。什么方法会更好?

根据历史是否不是域逻辑的一部分,我建议使用触发器。我的意思是,你不需要向用户展示它,你不需要复制历史版本

通过使用触发器,您有几个选项—最简单的(意味着您确实需要只为少数几个表保存历史记录)—就是拥有一个单独的历史记录表,它是原始表的副本


总而言之,这实际上取决于您的具体目标。

我为我们的应用程序编写了一个版本控制系统。我将版本对象分为两个类,一个代表整个对象,另一个代表其版本

在我们的软件中,版本控制是业务逻辑的一部分。应用程序提供对历史记录的访问,用户可以控制版本控制

因此,将在内存中创建一个新版本。您需要执行深度复制。您可以通过在根实体及其所有子实体中实现接口来实现这一点。此接口提供了一个通过对象图递归调用的方法
DeepCopy

object
中还有一个受保护的
MemberwiseCopy
方法,这可能会有所帮助。它不是深度复制

我们不想痛苦地维护复制每个属性的代码。因此,我们使用序列化在内存中复制对象图:

public static T CopyDataContract<T>(T obj)
{
    NetDataContractSerializer serializer = new NetDataContractSerializer();
    using (MemoryStream stream = new MemoryStream())
    {
        serializer.Serialize(stream, obj);
        stream.Position = 0;
        return (T)serializer.Deserialize(stream);
    }
}
publicstatict CopyDataContract(T obj)
{
NetDataContractSerializer=新的NetDataContractSerializer();
使用(MemoryStream stream=new MemoryStream())
{
serializer.Serialize(流,obj);
流位置=0;
返回(T)序列化程序。反序列化(流);
}
}
此外,我们在实体中有方法重置ID并执行一些其他清理。这也是通过对象图递归完成的

就目前而言,它运行良好。在将来,我们可能需要将其重构为接口实现,这样会更干净一些