2008-10-30 103 views
0

我有一个用户对象,它上面有一个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”。据推测这是因为Country对象被NHibernate标记为脏?我不想更新国家对象,只是用户的ID参考。这样做有可能吗?

感谢, 乔恩

回答

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

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

0

感谢安德斯。为什么我们需要额外的开销来获取对象:当我们正在做的是更新对该对象的引用时?

实际上,我们的控制器会自动反序列化对对象的请求。有没有办法可以告诉NHibernate忽略国家对象的更新并更新用户?我会认为级联=“无”会做到这一点。

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

+0

其实你不一定需要nhibernate来检索数据。 ISession的Load和Get之间有一个小的区别。其中一人懒洋洋地工作,另一人立即检索。 – Min 2008-11-06 18:44:12

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采取了这个设计决策?