データベース全体をエクスポート/インポートするのに役立つロジックを記述できる必要があります。もちろん、これを行うときはIDを無視する必要があるため、データをエクスポートしてからインポートすると、グラフ全体が複製されます。
アイデアは、カスタム コードを使用せずに単純なバイナリ シリアル化を使用することでした。そのため、必要なオブジェクトのグラフをシリアル化できます。しかし、私はNHibernateの問題に立ち止まりました。
問題は、このグラフには、単一の永続オブジェクトの実際には異なるオブジェクト (異なる参照) である多くのオブジェクトが含まれていることです。グラフが非常に複雑で、アプリケーション全体をやり直す必要があるため、これを修正するのは非常に困難です。だから私はこれと一緒に生きなければなりません。
すべてのグラフをファイルに保存してから逆シリアル化し、そのまま DB に保存しようとすると、これらのオブジェクトにはいくつかの ID が割り当てられるため、NHibernate はおそらく失敗します。IDをクリアする必要があります。しかし、これを行うと、NHibernate は各オブジェクトの ID を認識しなくなるため、すべてのオブジェクトは一時的なものであり、もちろん同じではありません。
例:
私は持っていUser {Id = 3}
ますMail {Id = 2, with User(Id = 3)}
ここの 2 人のユーザーは同じ ID を持っているため、同じです。しかし、参照は等しくありません。このグラフの ID をクリアすると、両方のユーザーが参照が等しくないため、異なるオブジェクトになります。
私は考えていました-オブジェクトにID(!= 0)がありますが、それらは一時的なものであり、DBに挿入する必要があり、新しいIDを受け取る必要があることをNHibernateに伝えることができますか?または、私の問題を解決する別の方法を知っているかもしれません。
PS すべてのオブジェクトは切り離されています - それらが永続的であると言うとき、私はそれらが Id != 0 を持ち、エクスポートする前に DB にコピーを持っていたことを意味します (別の DB であった可能性があります)
アップデート
作業したいコードの例を追加しました。最終的な呼び出しでは、SaveOrUpdate
実行ごとに 1 つのオブジェクトを挿入する必要があります。実際のコードはもう少し複雑ですが、s1 と s2 を含む単一の階層 (単一の永続オブジェクトを表す 2 つの異なるオブジェクト。それらの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);
}