1

私は2つのエンティティを持っています:

public class Parent()
{
    public ICollection<Child> Children { get; set; }
}

public class Child()
{
    public Parent Parent { get; set; }
}

マッピングは次のようになります。

public class ParentMap : ClassMap<Parent>
{
    HasMany(x => x.Children).Cascade.All().Inverse();
}

public class ChildMap : ClassMap<Child>
{
    References(x => x.Parent).Cascade.None();
}

通常、親または子を保存するには、次のようにする必要があります。

var parent = new Parent();
var child = new Child();

parent.Children.Add(child);
child.Parent = parent;

Session.SaveOrUpdate(parent);

つまり、NHibernate がこのエンティティを正しく保持するには、両方のオブジェクトでプロパティを設定する必要があります。

ただし、レガシーの問題については、両側を設定せずにこのエンティティを保存したいので、次のことができます。

var parent = new Parent();
var child = new Child();
child.Parent = parent;

Session.SaveOrUpdate(child);

この場合、子を親のChildrenコレクションに追加せずParent、子オブジェクトに を設定するだけです。

Childrenデータベースから親を取得すると、そのコレクション内に子が含まれるように、NHibernate にこれを正しく保持させる方法はありますか?

PS セッションキャッシュに潜在的な問題があり、NHibernate に依存してバックグラウンド操作を実行してデータモデルを正しくすることを認識していますが、今のところこの問題は無視しています。

4

1 に答える 1

2

親を子のプライベート フィールドとしてマップします。

public class ChildMap : ClassMap<Child>
{
    References(x => x.Parent).Cascade.None()
        .Access.CamelCaseField(Prefix.Underscore);
}

public プロパティを介して制御します。

public class Child()
{
    private Parent _parent;

    public Parent Parent
    {
        get { return _parent; }
        set
        {
            _parent = value;
            _parent.Children.Add(this);
        }
    }
}

しかし、現在のコードは期待どおりに動作するはずです。Child を Parent's Children コレクションに追加して NH に永続化させる必要はありません。これは、リレーションシップの逆側としてマークされているためです。これを追加して、メモリ内オブジェクトをデータベースと同期させます。子に親を設定し、セッションをフラッシュし、新しいセッションで親を再ロードすると、Children コレクションに子が含まれる必要があります (2 番目のレベルのキャッシュが機能しないと仮定します)。

編集: 子を親に追加するには、アクションをメソッドにカプセル化します。

public void AddChild(Child child)
{
    _children.Add(child);
    child.Parent = this;
}
于 2010-03-10T22:30:02.090 に答える