我正在使用最新版本的NHibernate,最近我偶然发现了一个有趣的问题。
假设我有一个名为Profile的表,我想收到所有个人资料的列表。但是,有了它,我有一个名为CanDelete
的计算列,它禁止在(例如)使用它时删除该配置文件。
但是,这个CanDelete
计算列不是我的实体的一部分,当我在这种情况下只需要CanDelete
值时,我不想污染实体 - 并为每一个单独计算它个人资料太慢了。
NHibernate中是否有一种方法可以执行某些查询并将该查询的行作为对象获取,但之后还会以某种方式获取其他计算列?
假设我使用的是N层架构。在表示层中我需要一个包含所有配置文件的列表(对于每个配置文件,我是否可以删除它)。我的业务逻辑层和数据访问层将如何?
现在,在我的存储库中,我有一个GetProfiles
方法,然后是我为每个获取的配置文件运行的CanDeleteProfile
方法。但就像我上面提到的那样,它太慢了。我可以创建一个GetProfilesWithCanDeleteStatus
方法,但这也需要我在其上创建一个带有该计算列的专用实体。
当我不希望在我的个人资料列表中点击O(n^2)
表现时,您对如何以正确的方式构建此内容有何建议?我想避免n + 1问题。
我不一定在寻找NHibernate解决方案(我标记了NHibernate,因为它可能有一些特定的工具用于此类事情),并欢迎其他ORM的一般解决方案。
答案 0 :(得分:0)
我有一个可能对你有好处的想法,但它不会是一个完美的想法,因为你设计程序的每一种方式都有它的缺点。
我建议您更改该列CanDelete
的定义,以便它就像该实体中的任何其他列(不是在运行时计算)和布尔类型,但不会损坏要求。
通过这样做,它就像数据库中的任何其他简单Select
- 这非常快。
现在,棘手的部分是确保该列表明(在任何时候需要)是否已被使用(以及是否可以删除)。
因为如果使用了Profile实体(并且可以删除),我不知道你计算的方式,很难说明如何设计DAL和BL,但指南是:
在每个其他地方,您更改DB(该实体或其他)的状态,可能会更改您使用函数更新列CanDelete
以再次计算该值以验证其状态并在需要时更改它
如果您确保每次更改BL中的一个CanDelete
计算的列,则确保列CanDelete
始终为真。
这种方法的缺点是: 1.它为程序员在需要时不使用封装功能的错误打开了一个位置。 2.假设这个应用程序是唯一一个更改此数据库的人。 3.从管理工作室或脚本插入原始数据时必须小心。
我希望它对你的BL有好处。