我需要能够编写一个逻辑来帮助我导出/导入整个数据库。当然,这样做时应该忽略 id,所以如果我导出数据,然后导入它 - 应该克隆整个图。
这个想法是使用简单的二进制序列化而不需要任何自定义代码 - 所以我可以序列化任何我想要的对象图。但我在 NHibernate 问题上停了下来。
问题是该图包含许多对象,这些对象实际上是单个持久对象的不同对象(不同的引用)。由于图表非常复杂,因此很难解决这个问题,我需要为此重做整个应用程序。所以我必须忍受这个。
如果我只是将所有图形保存到文件中,然后对其进行反序列化并尝试按原样保存到 DB - 这些对象将分配一些 id,因此 NHibernate 可能会失败。我需要清除身份证。但是如果我这样做 - NHibernate 不再知道每个对象的身份,所以每个对象都是瞬态的,当然,是不相等的。
例子:
我有User {Id = 3}
和Mail {Id = 2, with User(Id = 3)}
这里的两个用户具有相同的 ID - 所以他们是平等的。但不是参考相等。当我清除此图的 ID 时 - 两个用户都成为不同的对象,因为它们不是引用相等的。
我在想——我能不能告诉 NHibernate,即使对象有 id(!= 0),但它们是瞬态的,应该插入到数据库中,它们应该接收新的 Id。或者,也许您知道解决我的问题的另一种方法。
PS所有对象都是分离的-当我说它们是持久的时,我的意思是它们具有Id!= 0并且在导出之前它们在数据库中具有副本(可能是另一个数据库)
更新
我添加了一个我想要工作的代码示例。最后的SaveOrUpdate
调用应该每次运行都插入一个对象。实际的代码有点复杂,但问题是我有一个包含 s1 和 s2 的层次结构(两个不同的对象代表单个持久对象。它们的Equal() == true
, but ReferenceEqual == false
)我需要克隆它并保存它确保结果对象在数据库中是单一的。
User s1;
User s2;
using (var session = DBHandler.GetSessionFactory().OpenSession())
{
s1 = session.Get<User>(1);
}
using (var session = DBHandler.GetSessionFactory().OpenSession())
{
s2 = session.Get<User>(1);
}
var c1 = (User)DBHandler.DeepClone(s1);
var c2 = (User)DBHandler.DeepClone(s2);
// These updates should insert only one object, because it is actually one object.
using (var session = DBHandler.GetSessionFactory().OpenSession())
{
session.SaveOrUpdate(c1);
}
using (var session = DBHandler.GetSessionFactory().OpenSession())
{
session.SaveOrUpdate(c2);
}