我在User类和Place类之间有一个简单的多对多关系。此关系由用户的“邻居”属性
表示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();
}
创建用户时,会从数据库加载一些位置并添加到用户,其中一个位置设置为默认。当用户被持久化时,关联的UserPlace实体也会被持久化。
我遇到的问题是每个与UserPlace关联的 Place 实体也会更新。这不是理想的效果,我已经尝试通过将Cascade设置为None()来防止Cascade发生放置(双关语)......但是这并没有改变任何东西。
我只是通过指定不应更新Place上的每个属性([PropertyName] .Not.Updated())来设法停止此更新。这有效,但它不是解决方案。
有没有人对如何防止这种情况发生任何想法?
编辑:Place实体映射也指定了DynamicUpdate() - 因此在保存用户时实体不应该更改。
PS!我不认为它对这种情况有所影响(但我可能错了!),但也要考虑这一点: Place 实体是在NHibernate之外加载的(使用ADO.NET和存储过程,因为我无法用NHibernate进行一些地理空间查询,然后通过在每个实体上调用Session.Update()来附加到会话。
答案 0 :(得分:1)
这不是一个级联问题。 NH会更新地点,因为您会在每个地方拨打session.Update
。你在PS中写的内容与问题完全相关。
当您在分离的实体上调用update时,NH无法知道实体的状态是否实际发生了变化。为了避免在更新之前查询数据(两次数据库往返),它会盲目地更新数据。
为避免这种情况:
SelectBeforeUpdate
精通)session.Merge(place)
。它还会在更新之前执行查询。请注意,它具有需要使用的返回值。session.Load(place.Id)
创建相关地点的代理并进行分配(请注意,NH在访问代理的属性时会再次加载该地点)session.Lock(place, LockMode.None)
将对象放入会话中。