目前,我们使用 NHibernate 将业务对象映射到数据库表。所述业务对象执行业务规则:如果违反该属性的合同,集合访问器将当场抛出异常。此外,属性强制与其他对象的关系(有时是双向的!)。好吧,每当 NHibernate 从数据库加载对象时(例如,当调用 ISession.Get(id) 时),映射属性的 set 访问器用于将数据放入对象中。
好处是应用程序的中间层强制执行业务逻辑。不好的是数据库没有。有时垃圾会进入数据库。如果垃圾被加载到应用程序中,它就会退出(抛出异常)。有时它显然应该放弃,因为它不能做任何事情,但如果它可以继续工作呢?例如,收集实时报告的管理工具运行不必要的失败风险很高,而不是允许管理员甚至修复(潜在的)问题。
我现在没有一个例子,但在某些情况下,让 NHibernate 使用也强制关系(尤其是双向)的“前门”属性会导致错误。
什么是最好的解决方案?
目前,我将在每个属性的基础上为 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 中的属性名称和实体模型中的属性名称(即查询时使用的名称,例如 via HQL——只要你给 NHibernate 一个属性的名称(字符串)。这成为一个问题,起初,某些属性 Blah 的 BR 没有问题,因此您在 O/R 映射中引用它......但后来,您必须添加一些确实成为问题的 BR,所以那么您必须更改您的 O/R 映射以使用新的 _Blah 属性,该属性会破坏所有使用“Blah”的现有查询(针对字符串进行编程的常见问题)。
有没有人解决过这些问题?!