将投影添加到 NHibernate 标准会阻止其执行默认实体选择
我正在编写一个 NHibernate 标准来选择支持分页的数据。我使用 SQL Server 2005(+) 中的 COUNT(*) OVER()
表达式来获取可用行的总数,如 Ayende Rahien 建议。我需要这个数字才能计算出总共有多少页。该解决方案的优点在于我不需要执行第二个查询来获取行计数。
但是,我似乎无法编写工作标准(Ayende 仅提供 HQL 查询)。
这是一个 SQL 查询,它显示了我想要的内容,并且运行得很好。请注意,我故意省略了实际的分页逻辑来关注问题:
SELECT Items.*, COUNT(*) OVER() AS rowcount
FROM Items
这是 HQL:
select
item, rowcount()
from
Item item
请注意,rowcount() 函数是在自定义 NHibernate 方言中注册的,并解析为 COUNT(* ) SQL 中的 OVER()。
要求是使用条件来表达查询。不幸的是,我不知道如何正确处理:
var query = Session
.CreateCriteria<Item>("item")
.SetProjection(
Projections.SqlFunction("rowcount", NHibernateUtil.Int32));
每当我添加投影时,NHibernate 都不会选择 item
(就像没有投影时一样),只是选择 rowcount()< /code> 虽然我真的需要两者。另外,我似乎无法将
item
作为一个整体来投影,只能投影它的属性,而且我真的不想列出所有这些属性。
我希望有人能解决这个问题。不管怎样,谢谢。
I'm writing an NHibernate criteria that selects data supporting paging. I'm using the COUNT(*) OVER()
expression from SQL Server 2005(+) to get hold of the total number of available rows, as suggested by Ayende Rahien. I need that number to be able to calculate how many pages there are in total. The beauty of this solution is that I don't need to execute a second query to get hold of the row count.
However, I can't seem to manage to write a working criteria (Ayende only provides an HQL query).
Here's an SQL query that shows what I want and it works just fine. Note that I intentionally left out the actual paging logic to focus on the problem:
SELECT Items.*, COUNT(*) OVER() AS rowcount
FROM Items
Here's the HQL:
select
item, rowcount()
from
Item item
Note that the rowcount()
function is registered in a custom NHibernate dialect and resolves to COUNT(*) OVER()
in SQL.
A requirement is that the query is expressed using a criteria. Unfortunately, I don't know how to get it right:
var query = Session
.CreateCriteria<Item>("item")
.SetProjection(
Projections.SqlFunction("rowcount", NHibernateUtil.Int32));
Whenever I add a projection, NHibernate doesn't select item
(like it would without a projection), just the rowcount()
while I really need both. Also, I can't seem to project item
as a whole, only it's properties and I really don't want to list all of them.
I hope someone has a solution to this. Thanks anyway.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我认为这在 Criteria 中是不可能的,它有一些限制。
您可以在后续查询中获取 id 并加载项目:
如果您不喜欢它,请使用 HQL,您也可以在那里设置最大结果数:
I think it is not possible in Criteria, it has some limits.
You could get the id and load items in a subsequent query:
If you don't like it, use HQL, you can set the maximal number of results there too:
使用创建多条件。
这样,您只需对数据库进行一次点击即可执行 2 个简单的语句。
Use CreateMultiCriteria.
You can execute 2 simple statements with only one hit to the DB that way.
我想知道为什么需要使用 Criteria。你不能使用session.CreateSQLQuery吗?如果您确实必须在一个查询中执行此操作,我建议拉回 Item 对象和计数,例如:
...这样您就可以从查询中获取 Item 对象以及计数。如果您遇到 Hibernate 缓存问题,您还可以配置与本机查询关联的查询空间(实体/表缓存),以便自动清除过时的查询缓存条目。
I am wondering why using Criteria is a requirement. Can't you use session.CreateSQLQuery? If you really must do it in one query, I would have suggested pulling back the Item objects and the count, like:
...this way you can get back Item objects from your query, along with the count. If you experience a problem with Hibernate's caching, you can also configure the query spaces (entity/table caches) associated with a native query so that stale query cache entries will be cleared automatically.
如果我正确理解你的问题,我就有一个解决方案。我在同样的问题上挣扎了很多。
让我快速描述一下我遇到的问题,以确保我们意见一致。我的问题归结为分页。我想在 UI 中显示 10 条记录,但我还想知道与过滤条件匹配的记录总数。我想使用 NH criteria API 来完成此任务,但是当添加行数投影时,我的查询不再起作用,并且我不会得到任何结果(我不记得具体的错误,但听起来像你的正在得到)。
这是我的解决方案(从我当前的生产代码复制并粘贴)。请注意,“SessionError”是我正在检索分页数据的业务实体的名称,根据 3 个过滤条件:IsDev、IsRead 和 IsResolved。
因此,我创建了我的基本标准,并带有可选的限制。然后我克隆它,并将行计数投影添加到克隆条件中。请注意,我在添加分页限制之前克隆了它。然后,我设置一个 IMultiCriteria 来包含原始和克隆的 ICriteria 对象,并使用 IMultiCriteria 执行它们。现在,我有了来自原始 ICriteria 的分页数据(并且我只通过网络拖动了所需的数据),以及有多少实际记录符合我的条件的原始计数(对于显示或创建分页链接等很有用)。这个策略对我来说效果很好。我希望这有帮助。
If I understand your question properly, I have a solution. I struggled quite a bit with this same problem.
Let me quickly describe the problem I had, to make sure we're on the same page. My problem came down to paging. I want to display 10 records in the UI, but I also want to know the total number of records that matched the filter criteria. I wanted to accomplish this using the NH criteria API, but when adding a projection for row count, my query no longer worked, and I wouldn't get any results (I don't remember the specific error, but it sounds like what you're getting).
Here's my solution (copy & paste from my current production code). Note that "SessionError" is the name of the business entity I'm retrieving paged data for, according to 3 filter criterion: IsDev, IsRead, and IsResolved.
So I create my base criteria, with optional restrictions. Then I CLONE it, and add a row count projection to the CLONED criteria. Note that I clone it before I add the paging restrictions. Then I set up an IMultiCriteria to contain the original and cloned ICriteria objects, and use the IMultiCriteria to execute both of them. Now I have my paged data from the original ICriteria (and I only dragged the data I need across the wire), and also a raw count of how many actual records matched my criteria (useful for display or creating paging links, or whatever). This strategy has worked well for me. I hope this is helpful.
我建议通过在会话中调用 SetResultTransformer() 来调查自定义结果转换器。
I would suggest investigating custom result transformer by calling SetResultTransformer() on your session.
在类映射中创建公式属性:
Create a formula property in the class mapping: