时间:2010-07-22 16:54:37

标签: c# asp.net-mvc nhibernate

这有效:

public ActionResult Save(int id, string name)
{
    var profile = _profileRepository.GetById(id);
    profile.Name = name;
    _profileRepository.Save(profile); //this calls SaveOrUpdate()

    //session.Commit() gets called in global.asax on Application_EndRequest()
    //profile.Name is changed in the database
}

由于我的实际问题比这个简单的例子更复杂,我想从repo获取配置文件,在配置文件上使用TryUpdateModel来更新任何更改,然后保存。但是,当我将TryUpdateModel引入混合时,它会因NonUniqueObjectException而失败(具有相同标识符值的另一个对象已经与会话关联):

public ActionResult Save(int id)
{
    var profile = _profileRepository.GetById(id); 
    TryUpdateModel(profile); //this works from the looks of it
    _profileRepository.Save(profile); //this also appears to work;

    //fails on session.Commit()
    //nothing changed in database
}

具有相同标识符值的“不同”对象??看起来好像TryUpdateModel正在断开我的配置文件对象与会话。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

第一个例子可行,因为你正在更新通过NHibernate Session检索的同一个对象。

第二个示例可能会失败,因为TryUpdateModel()可能会替换配置文件对象的属性(如果存在匹配的ValueProvider数据)。如果您偶然发布其中一个属性(包括Id)的数据,TryUpdateModel()方法可能会替换最初通过NHibernate会话检索的其中一个对象。当您尝试保存配置文件时,NHibernate将识别您没有编辑原始对象,但是正在尝试使用完全相同的Id保存其他对象。这将导致NonUniqueObjectException。

要解决此问题,您应确保更新从Session中检索的原始实体的值。我建议您避免直接针对您希望对其执行更改跟踪的域中的实体使用DefaultModelBinder。