我应该用NHibernate映射哪些类?

我应该用NHibernate映射哪些类?,nhibernate,business-logic,business-rules,Nhibernate,Business Logic,Business Rules,目前,我们使用NHibernate将业务对象映射到数据库表。上述业务对象强制执行业务规则:如果违反该属性的约定,集合访问器将当场抛出异常。此外,属性还强制与其他对象的关系(有时是双向的!)。好的,每当NHibernate从数据库加载一个对象时(例如,当ISession.Get(id)被调用时),映射属性的set访问器被用来将数据放入对象中 好的是,应用程序的中间层强制执行业务逻辑。糟糕的是数据库没有。有时垃圾会进入数据库。如果垃圾被加载到应用程序中,它将退出(抛出异常)。有时它显然应该退出,因为

目前,我们使用NHibernate将业务对象映射到数据库表。上述业务对象强制执行业务规则:如果违反该属性的约定,集合访问器将当场抛出异常。此外,属性还强制与其他对象的关系(有时是双向的!)。好的,每当NHibernate从数据库加载一个对象时(例如,当ISession.Get(id)被调用时),映射属性的set访问器被用来将数据放入对象中

好的是,应用程序的中间层强制执行业务逻辑。糟糕的是数据库没有。有时垃圾会进入数据库。如果垃圾被加载到应用程序中,它将退出(抛出异常)。有时它显然应该退出,因为它什么也做不了,但如果它能继续工作呢?例如,收集实时报告的管理工具存在不必要地失败的高风险,甚至不允许管理员修复(潜在)问题

我现在还没有一个例子,但在某些情况下,让NHibernate使用“前门”属性也强制关系(尤其是bidi)会导致bug

最好的解决方案是什么

目前,我将在每个酒店的基础上,为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”(针对字符串编程的常见问题)中断所有现有查询


有人解决了这些问题吗

虽然我发现您的大多数架构都有问题,但处理这些问题的通常方法是让NHibernate使用backing字段而不是setter

在上面的示例中,不需要定义其他受保护的属性。只需在映射中使用此选项:

<property name="Blah" access="nosetter.lowercase"/>


这在文档中有描述,(表5.1.访问策略)

不清楚为什么不能阻止无效数据进入数据库。我不认为该场景有一个通用的解决方案(无论是否涉及NHibernate)。您可以不断轮询数据库以查找无效数据,然后在NHibernate尝试加载数据之前以某种方式尝试更正它。刚刚发现一个相关的讨论:@Michael:好问题/评论。一般来说,它是一个遗留应用程序,其中先前存在的数据不符合业务要求(我知道我们应该清理它),或者另一个遗留应用程序允许坏数据进入。这实际上是Hibernate的首选访问策略:从数据库读取数据时不应强制执行业务规则,您应该只获取其中的数据。出于某种原因,NHibernate的人不同意并提倡/推荐属性访问策略。这可能是因为setter通常不在.NET/NHibernate强制执行规则的地方。事实上,大多数持久性实体都使用自动属性,因此会生成getter/setter实体。谢谢您的评论@Diego,在我看来,这个解决方案将减少在C#2代码中胡扯的视图(只是属性和字段)。但在C#3中,它需要我有两个层开始(属性和字段)——即Blah不能是默认属性;无论是否有任何业务逻辑要实现,都必须手工编码。“我理解对了吗?”阿波罗,我不明白这个问题。这并不意味着在现有代码中增加一层,因为您已经在使用非自动属性;您实际上正在删除一个层(受保护的属性)。很抱歉,这不清楚。你的回答回答了我的问题。我说你的解决方案需要2个,而不是差不多。为了澄清,它比上面的C#2示例要少。但是,您的解决方案意味着我不能从默认属性开始(通过C#3)。我同意。我只是想确定我明白你的意思。