将集合查询从 SQL 转换为 nhibernate
我有一个数据库架构,其中有一个 Product
、Category
、CategoryFeature
和 ProductCategoryFeatureValue
。
该模型是使用 Fluent NHibernate 映射的,但基本上如下。
Product
-------
ID
Title
Category
--------
ID
Title
CategoryFeature
---------------
ID
CategoryID
Title
ProductCategoryFeatureValue
---------------
ID
ProductID
CategoryFeatureID
_______________________
Category [one] <-> [many] CategoryFeature
Product [many] <-> [many] ProductCategoryFeatureValue
基本上,产品可用的功能都列在 ProductCategoryFeatureValue
表中,该表是多对多集合的“中间链接”。
我需要创建一个查询,在其中可以找到具有用户选择的所有功能的所有产品。
例如,搜索 ID 为 643229 和 643229 的两个要素。 667811 在 SQL 术语中,我会做这样的事情:
SELECT * FROM Product
JOIN ProductCategoryFeatureValue AS feature1 ON Product.id = feature1.ProductID AND feature1.categoryfeatureid = 643229
JOIN productcategoryfeaturevalue AS feature2 ON Product.id = feature2.ProductID AND feature2.categoryfeatureid = 667811
我可以做的另一个查询是这样的:
SELECT * FROM product WHERE
((SELECT id FROM productcategoryfeaturevalue AS feature1 WHERE feature1.ItemGroupID = product.id AND feature1.categoryFeatureID = 643229 LIMIT 1) IS NOT NULL)
AND
((SELECT id FROM productcategoryfeaturevalue AS feature2 WHERE feature2.ItemGroupID = product.id AND feature2.categoryFeatureID = 667811 LIMIT 1) IS NOT NULL)
两者都经过测试并且运行良好。但是,我似乎无法使用 NHibernate 重现它们。有什么想法吗?
谢谢!
I have a database schema, where I have a Product
, Category
, CategoryFeature
, and an ProductCategoryFeatureValue
.
The Model is mapped using Fluent NHibernate, but basically is as follows.
Product
-------
ID
Title
Category
--------
ID
Title
CategoryFeature
---------------
ID
CategoryID
Title
ProductCategoryFeatureValue
---------------
ID
ProductID
CategoryFeatureID
_______________________
Category [one] <-> [many] CategoryFeature
Product [many] <-> [many] ProductCategoryFeatureValue
Basically, the features available to a product are listed in the ProductCategoryFeatureValue
table, which is the 'middle-link' for the many-to-many collection.
I need to create a query, where i can find all products, which have ALL the features selected by the user.
Example, doing a search for two features with ids 643229 & 667811 in SQL terms, I would do something like this:
SELECT * FROM Product
JOIN ProductCategoryFeatureValue AS feature1 ON Product.id = feature1.ProductID AND feature1.categoryfeatureid = 643229
JOIN productcategoryfeaturevalue AS feature2 ON Product.id = feature2.ProductID AND feature2.categoryfeatureid = 667811
Another query which I could do is this:
SELECT * FROM product WHERE
((SELECT id FROM productcategoryfeaturevalue AS feature1 WHERE feature1.ItemGroupID = product.id AND feature1.categoryFeatureID = 643229 LIMIT 1) IS NOT NULL)
AND
((SELECT id FROM productcategoryfeaturevalue AS feature2 WHERE feature2.ItemGroupID = product.id AND feature2.categoryFeatureID = 667811 LIMIT 1) IS NOT NULL)
Both have been tested and work well. However, I cannot seem to reproduce them using NHibernate. Any ideas?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我相信您希望在 SQL 中实现类似的功能,
这样您就不必为用户选择的每个功能多次 JOIN 到 ProductCategoryFeatureValue 表。至少你会得到一个更好的查询计划。如果您不喜欢 IN 子句,您也可以使用临时表。
就将其转换为 NHibernate 而言,它不支持 Criteria API 中的任何 HAVING 子句逻辑,但使用 HQL 支持。
HQL 示例
I believe you want something like this in SQL
That will stop you having to JOIN to the ProductCategoryFeatureValue table multiple times for every feature selected by the user. At the very least your going to get a nicer query plan. If you don't like the IN clause you could also use a temp table instead.
In terms of translating this into NHibernate it doesn't support any HAVING clause logic in the Criteria API but it is supported using HQL.
HQL Examples
从问题中不能 100% 确定您的映射到底是什么,但这可能接近您需要的
如果“Expression.In”不完全符合您的要求,您可以快速循环添加
Not 100% sure from the question exactly what your mappings are but this may be close to what you need
If the "Expression.In" doesn;t quite do what you are after you could just do a quick loop adding
我认为你最大的问题是在连接上添加条件。我还没有尝试过,但一直期待 NH 3.+ 的功能,它可以让您添加条件加入。
CreateAlias(字符串关联路径,字符串别名,JoinType joinType,ICriterion withClause)CreateCriteria(字符串关联路径,字符串别名,JoinType joinType,ICriterion withClause)
I think your biggest problem is adding a condition on a join. I haven't tried it yet, but have been looking forward to the feature of NH 3.+ that lets you add a criteria join.
CreateAlias(string associationPath, string alias, JoinType joinType, ICriterion withClause) CreateCriteria(string associationPath, string alias, JoinType joinType, ICriterion withClause)