1

我在 User 类和 Place 类之间有一个简单的多对多关系。这种关系由用户的“邻居”属性表示

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

UserPlace 类只是一个组件,它向 User 和 Place 之间的关系添加了一条信息:

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();
}

创建用户时,会从数据库中加载多个 Places 并将其添加到用户中,其中一个设置为default。当用户被持久化时,关联的 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里写的绝对和问题有关。

当您在分离实体上调用更新时,NH 无法知道实体的状态是否实际更改。为了避免在更新(两次数据库往返)之前查询数据,它盲目地更新数据。

为了避免这种情况:

  • 设置更新前选择(SelectBeforeUpdate流利)
  • 使用session.Merge(place). 它还在更新之前执行查询。请注意,它有一个需要使用的返回值。
  • 用于session.Load(place.Id)创建相关地点的代理并分配它(注意 NH 在访问代理的属性时会再次加载该地点)
  • 用于session.Lock(place, LockMode.None)将对象放入会话中。
  • 使用 NH 查询检索 Places。
于 2011-04-19T14:06:40.803 回答