1

NHibernate を使用して、単純な 1 対多の関係/階層を作成しようとしています。孤児を自動的に削除したいのですが、現在そうしようとしても ObjectDeletedException が発生します。誰かが私が間違っていることを教えてくれるかどうか疑問に思っています。

編集:

ルート Foo をロードしてから、子をセッション外に削除して、1 つまたは複数の子を孤立させることを指定する必要がありました。その後、2 番目のセッションで SaveOrUpdate(root) を呼び出すと、例外が発生します。デタッチされて変更されたオブジェクトと、データベースに永続化されているオブジェクトとの間の子のリストの違いを修正するにはどうすればよいですか?

問題のサンプル コードは次のようになります。

Foo foo = new Foo();
Foo child1 = new Foo();
Foo child2 = new Foo();

foo.Children.Add(child1);
child1.Children.Add(child2);

// session #1
session.SaveOrUpdate(foo);

// so far, so good

// outside of any session
foo.Children.Clear();

// session #2
PutFoo(foo); // results in ObjectDeletedException

永続化されるオブジェクト:

class Foo
{
    private IList<Foo> children = new List<Foo> children;

    public virtual int Id { get; private set; }
    public IList<Foo> Children
    {
        get { return children; }
        set { children = value; }
    }
}

FluentNHibernate マッピング:

class FooMap : ClassMap<SyncDir>
{
    public FooMap()
    {
        Id(x => x.Id);
        base.HasMany(x => x.Children).Cascade.AllDeleteOrphan();
     }
}

タイプ Foo のオブジェクトを永続化するために使用されるメソッド:

void PutFoo(Foo foo)
{
    using (var session = factory.OpenSession())
    using (var transaction = factory.BeginTransaction())
    {
        session.SaveOrUpdate(foo);
        transaction.Commit();
    }
}
4

1 に答える 1

1

私が常に行っているのは、双方向の関係を作成することです。

したがって、これは、子が親への参照を持っていることを意味します。コレクションから子を削除するときは、親への参照も NULL に設定します。

マッピングでは、関係の「逆」の端も示す必要があります。また、コレクションを「そのまま」クラス外に公開することもありません。

したがって、私は主に次のようにします。

public class Foo
{
   private ISet<Bar> _bars = new HashSet<Bar>();

   public ReadOnlyCollection<Bar> Bars { get return new List<Bar>(_bars).AsReadOnly(); }

   public void AddBar( Bar b )
   {
      b.Parent = this;
      _bars.Add (b);
   }

   public void RemoveBar( Bar b )
   {
      b.Foo = null;
      _bars.Remove (b);
   }
}


public class Bar
{
     public Foo Parent { get; set; }
}

次に、マッピングで、コレクションに「逆」エンドを設定します。したがって、これは、私のマッピング (マッピングを指定するためにまだ xml ファイルを使用しています) で、Foo クラスの Bars コレクションに inverse=true 属性を設定することを意味します。

于 2009-09-24T22:11:40.500 に答える