更新多对一关系

时间:2008-10-30 18:42:04

标签: nhibernate

我有一个User对象,上面有一个Country对象。我在用户映射文件中用多对一标签映射它:

<many-to-one name="Country" column="CountryID" cascade="none"/>

如何更新用户所在的国家/地区?

目前,我的用户界面有一个国家/地区下拉列表,新国家/地区的ID会传递给控制器​​。然后,控制器根据该值设置用户所在国家/地区的ID。所以:

var user = session.Get<User>(userID);
user.Country.ID = Convert.ToInt32(Request.Form["Country_ID"]);

但是当我打电话时:

session.SaveOrUpdate(user);

我收到一条错误消息,说“国家/地区实例的标识符已从7更改为8”。大概这是因为NHibernate将Country对象标记为脏了?我不想更新国家/地区对象,只是用户中的ID引用。有可能这样做吗?

谢谢, 乔恩

5 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

var user = session.Get<User>(userID);
user.Country = session.Get<Country>(Convert.ToInt32(Request.Form["Country_ID"]));

您必须从数据库中检索国家/地区,然后将其设置为用户

答案 2 :(得分:0)

感谢安德斯。当我们所做的只是更新对该对象的引用时,为什么我们需要首先获取对象的额外开销?

实际上,我们的控制器会自动反序列化对象的请求。难道我们无法告诉NHibernate忽略国家/地区对象的更新而只是更新用户?我原以为cascade =“none”会这样做。

如果对象上有多个需要更新的多对一对象,会发生什么?在保存之前将它们全部收回,这是一个很大的开销。

答案 3 :(得分:0)

这真的会否定首先使用ORM的整个目的,不是吗?更新像这样的子对象的正常模式是什么?当然这是一种非常常见的情况。是加载每一个:

var user = session.Get<User>(userID);
user.Country = session.Get<Country>(Convert.ToInt32(Request.Form["Country_ID"]));
user.Manager = session.Get<User>(Convert.ToInt32(Request.Form["Manager_ID"]));
user.State = session.Get<State>(Convert.ToInt32(Request.Form["State _ID"]));
user.Region = session.Get<Region>(Convert.ToInt32(Request.Form["State _ID"]));

我们是否真的需要为每个子对象进行额外的数据库调用(事件虽然这些对象没有被更新)?

目前我们有:

var ds = new NameValueDeserializer();
var entity = session.Get<TEntity>(entityID);
ds.Deserialize(entity, form);
session.Update(entity);

因此,这通常适用于所有实体。必须专门加载子对象以保存实体将是不必要的编码开销(以及进行额外的数据库调用)。

在配置,映射,拦截器等方面是否没有办法解决这个问题?有谁知道为什么Hibernate采取了这个设计决定?

答案 4 :(得分:0)

你应该把这个讨论带到NHibernate用户组。

http://groups.google.com/group/nhusers