【问题标题】:NHibernate update referenceNHibernate 更新参考
【发布时间】:2009-11-19 17:41:19
【问题描述】:

实体

我们有一个名为 Product 的实体,它是使用 NHibernate 加载的。

产品有一个类别,NHibernate 很乐意为我填充。

数据库

在数据库中,Product 有一个类别的外键。

场景

用户编辑此产品(通过网络界面)并选择不同的类别(例如,我们选择“蔬菜”而不是“鱼”)。

这可能是一个下拉列表,显示了每个类别。当他们选择不同的类别时,我们会得到一个 int 键。

问题

显然我们现在想要保存对 Product 的更改,但实际上唯一的更改是保存一个新的 int(比如 2,而不是 1)。

所以我们检索现有的产品,现在问题来了。

我们在 Product 上没有“CategoryID”字段,我们只有一个 Category 属性。

但我们并不想仅仅为了将其分配给产品而检索类别(按 id)。

所以我想我想知道的是我们应该……

a) 将 CategoryID 属性添加到 Product

b) 创建一个新类别,为其分配相关 id 并将其附加到 Product(但这肯定会导致错误,或覆盖现有类别)

c) 从系统中检索(查找)类别(按 id)并将其附加到产品

d) 完全做其他事情!

【问题讨论】:

    标签: nhibernate orm saving-data


    【解决方案1】:

    您似乎可以使用 Session.Load(id) 功能。

    Session.Load 是一种特殊的方法,它返回一个带有 ID 的代理,直到您请求另一个属性时它才会加载。如果没有与 ID 匹配的项目,则会引发错误。尝试类似:

    product.Category = Session.Load<Category>(2); //2 being the new category ID
    
    Session.SaveOrUpdate(product);
    

    我只是做了一点测试,似乎并没有拉回整个类别。

    【讨论】:

    • 现在我不知道该怎么做...我在更新现有实体时使用 Load,但您是否也应该对每个引用使用 Load?嗯
    • NHibernate 的一个好规则是使 Identity 列的 setter 为私有或受保护。这将不允许您像在答案中那样分配 ID。查看 SharpArchitecture 以获得良好的实现以及如何在测试中修改 Id。如前所述,除非请求属性,否则 Session.Load 不会对数据库执行任何操作,因此我们基本上与您的答案相同,只是使用了一个更智能的对象,该对象可以在需要时自行解析。
    【解决方案2】:

    更新:Session.Load 是correct answer

    product.Category = session.Load<Category>(2);
    
    session.Save(product);
    

    【讨论】:

    • 是的,这似乎有效。我遇到的唯一轻微的复杂情况是,对于一个可为空的日期时间字段,我需要确保我的映射和模型反映了它可以为空的事实(否则 NHibernate 会抛出关于无效日期时间值的错误)
    • 但是那个可以为空的日期是在产品上(不是类别)对吧?
    【解决方案3】:

    使用 NH 的EnumStringType&lt;T&gt; 将您的类别作为枚举映射到相应的数据库值(可以是字符串或数字)。如果你用谷歌搜索,你会发现很多用法示例。

    HTH!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      相关资源
      最近更新 更多