我应该使用 NHibernate 映射哪些类?
目前,我们使用 NHibernate 将业务对象映射到数据库表。所述业务对象强制执行业务规则:如果违反该属性的约定,则集合访问器将立即抛出异常。此外,这些属性还强制与其他对象建立关系(有时是双向的!)。好吧,每当 NHibernate 从数据库加载一个对象时(例如,当调用 ISession.Get(id) 时),映射属性的 set 访问器就用于将数据放入该对象中。
好处是应用程序的中间层强制执行业务逻辑。糟糕的是数据库没有。有时垃圾会进入数据库。如果垃圾被加载到应用程序中,它就会退出(抛出异常)。有时它显然应该放弃,因为它无能为力,但如果它可以继续工作怎么办?例如,收集实时报告的管理工具存在不必要的失败的高风险,而不是允许管理员修复(潜在的)问题。
我现在没有关于我的示例,但在某些情况下,让 NHibernate 使用也强制关系(尤其是 bidi)的“前门”属性会导致错误。
最好的解决方案是什么?
目前,我将在每个属性的基础上,为 NHibernate 创建一个“后门”:
public virtual int Blah {get {return _Blah;} set {/*enforces BR's*/}}
protected virtual int _Blah {get {return blah;} set {blah = value;}}
private int blah;
我在 C# 2 中展示了上述内容(无默认属性),以演示这如何让我们基本上获得 3 层或视图,等等。 !!!虽然这确实有效,但它似乎并不理想,因为它要求 BL 为整个应用程序提供一个(公共)接口,并为数据访问层提供另一个(受保护)接口。
还有一个额外的问题:据我所知,NHibernate 没有给你一种方法来区分 BL 中的属性名称和实体模型中的属性名称(即你查询时使用的名称,例如通过HQL——每当你给 NHibernate 一个属性的名称(字符串)时)。当首先,某些属性的 BR 没有问题时,这就会成为一个问题,因此您在 O/R 映射中引用它......但后来,您必须添加一些确实成为问题的 BR,因此那么您必须更改 O/R 映射以使用新的 _Blah 属性,这会破坏使用“Blah”的所有现有查询(针对字符串编程的常见问题)。
这些问题有人解决了吗?!
Currently, we use NHibernate to map business objects to database tables. Said business objects enforce business rules: The set accessors will throw an exception on the spot if the contract for that property is violated. Also, the properties enforce relationships with other objects (sometimes bidirectional!). Well, whenever NHibernate loads an object from the database (e.g. when ISession.Get(id) is called), the set accessors of the mapped properties are used to put the data into the object.
What's good is that the middle tier of the application enforces business logic. What's bad is that the database does not. Sometimes crap finds its way into the database. If crap is loaded into the application, it bails (throws an exception). Sometimes it clearly should bail because it cannot do anything, but what if it can continue working? E.g., an admin tool that gathers real-time reports runs a high risk of failing unnecessarily instead of allowing an admin to even fix a (potential) problem.
I don't have an example on me right now, but in some instances, letting NHibernate use the "front door" properties that also enforce relationships (especially bidi) leads to bugs.
What are the best solutions?
Currently, I will, on a per-property basis, create a "back door" just for NHibernate:
public virtual int Blah {get {return _Blah;} set {/*enforces BR's*/}}
protected virtual int _Blah {get {return blah;} set {blah = value;}}
private int blah;
I showed the above in C# 2 (no default properties) to demonstrate how this gets us basically 3 layers of, or views, to blah!!! While this certainly works, it does not seem ideal as it requires the BL to provide one (public) interface for the app-at-large, and another (protected) interface for the data access layer.
There is an additional problem: To my knowledge, NHibernate does not give you a way to distinguish between the name of the property in the BL and the name of the property in the entity model (i.e. the name you use when you query, e.g. via HQL--whenever you give NHibernate the name (string) of a property). This becomes a problem when, at first, the BR's for some property Blah are no problem, so you refer to it in your O/R mapping... but then later, you have to add some BR's that do become a problem, so then you have to change your O/R mapping to use a new _Blah property, which breaks all existing queries using "Blah" (common problem with programming against strings).
Has anyone solved these problems?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
虽然我发现你的大部分架构都有问题,但处理这些问题的常用方法是让 NHibernate 使用支持字段而不是 setter。
在上面的示例中,您不需要定义额外的受保护属性。只需在映射中使用它:
文档中对此进行了描述, http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-property(表 5.1. 访问策略)
While I found most of your architecture problematic, the usual way to deal with this stuff is having NHibernate use the backing field instead of the setter.
In your example above, you don't need to define an additional protected property. Just use this in the mapping:
This is described in the docs, http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-property (Table 5.1. Access Strategies)