1

UserクラスとPlaceクラスの間には単純な多対多の関係があります。この関係は、ユーザーの「Neighbourhood」プロパティによって表されます

public class User
{
  public virtual IList<UserPlace> Neighbourhood { get; set; }
}

UserPlaceクラスは、ユーザーとプレイスの関係に単一の情報を追加する単なるコンポーネントです。

public class UserPlace
{
  public virtual User User { get; set; }
  public virtual Place Place { get; set; }
  public virtual bool IsDefault { get; set; }
}

関係は次のようにマップされます。

public class UserMappings : ClassMap<User>
{
  //... other mappings

  HasMany(x => x.NeighbourHood)
            .Component(c =>
                           {
                               c.Map(x => x.IsDefault);
                               c.References(x => x.Place).Cascade.None();
                           }
            ).Not.LazyLoad().Cascade.SaveUpdate();
}

ユーザーが作成されると、いくつかのプレイスがデータベースから読み込まれ、ユーザーに追加されます。そのうちの1つがデフォルトに設定されています。ユーザーが永続化されると、関連付けられたUserPlaceエンティティも永続化されます。

私が経験している問題は、UserPlaceに関連付けられている各Placeエンティティも更新されることです。これは望ましい効果ではありません。CascadeをNone()に設定して、Cascade to Placeが発生しないようにしました(しゃれは意図されていません)...ただし、これによって何も変わりません。

Placeの各プロパティを更新しないように指定することで、この更新の実行を停止することができました([PropertyName] .Not.Updated())。これは機能しますが、解決策ではありません。

誰かがこれを防ぐ方法について何かアイデアがありますか?

編集:PlaceエンティティマッピングにはDynamicUpdate()も指定されているため、ユーザーが保存されたときにエンティティが実際に変更されることはありません。

PS!このシナリオに違いはないと思いますが(間違っているかもしれません!)、これも考慮してください:PlaceエンティティはNHibernateの外部にロードされます(地理空間クエリのため、ADO.NETとストアドプロシージャを使用します) NHibernateでは実行できませんでした)、各エンティティでSession.Update()を呼び出してセッションに接続しました。

4

1 に答える 1

1

これはカスケードの問題ではありません。NHは、場所session.Updateごとに電話をかけるため、場所を更新します。PSに書き込む内容は、問題に完全に関連しています。

デタッチされたエンティティでupdateを呼び出すと、NHはエンティティの状態が実際に変更されたかどうかを知ることができません。更新前のデータのクエリ(2回のデータベースラウンドトリップ)を回避するために、データを盲目的に更新します。

これを回避するには:

  • 更新前の選択を設定します(SelectBeforeUpdate流暢に)
  • を使用しsession.Merge(place)ます。また、更新前にクエリを実行します。使用する必要のある戻り値があることに注意してください。
  • 問題の場所のプロキシを作成して割り当てるために使用session.Load(place.Id)します(プロキシのプロパティにアクセスするときにNHがその場所を再度ロードすることに注意してください)
  • session.Lock(place, LockMode.None)オブジェクトをセッションに入れるために使用します。
  • NHクエリを使用して、場所を取得します。
于 2011-04-19T14:06:40.803 に答える