代码之家  ›  专栏  ›  技术社区  ›  JontyMC

更新多对一关系

  •  0
  • JontyMC  · 技术社区  · 16 年前

    我有一个用户对象,上面有一个国家对象。我在用户映射文件中将此标记映射为多对一标记:

    <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 回复  |  直到 16 年前
        1
  •  0
  •   loraderon    16 年前

    您可能应该将此讨论带到nhibernate用户组。

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

        2
  •  1
  •   loraderon    16 年前
        3
  •  0
  •   loraderon    16 年前
    var user = session.Get<User>(userID);
    user.Country = session.Get<Country>(Convert.ToInt32(Request.Form["Country_ID"]));
    

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

        4
  •  0
  •   JontyMC    16 年前

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

    实际上,我们的控制器自动将请求反序列化到对象。我们是否无法告诉nhibernate忽略country对象的更新并只更新用户?我本以为cascade=“none”会这样做的。

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

        5
  •  0
  •   JontyMC    16 年前

    这真的否定了使用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做了这个设计决定吗?