反转NHibernate查询的逻辑
我使用反转NHibernate查询的逻辑,nhibernate,nhibernate-criteria,Nhibernate,Nhibernate Criteria,我使用NHibernate构建了以下查询,它将为我提供一个MenuView项的集合,这些项包含给定的页面(由页面id引用) 它仍然返回确实包含id为8的页面的菜单项的结果。为什么这种简单的逻辑反转在代码方面不是那么简单 [更新] 采纳Firo的建议,将建议的查询更改为 // Only retrieve menus that do NOT contain this referenced page .CreateCriteria("Pages") .Add(Subqueries.PropertyNo
NHibernate
构建了以下查询,它将为我提供一个MenuView
项的集合,这些项包含给定的页面(由页面id引用)
它仍然返回确实包含id为8的页面的菜单项的结果。为什么这种简单的逻辑反转在代码方面不是那么简单
[更新]
采纳Firo的建议,将建议的查询更改为
// Only retrieve menus that do NOT contain this referenced page
.CreateCriteria("Pages")
.Add(Subqueries.PropertyNotIn("Id", querymenuItemswithPage)) <--- query you have would be here
)
一开始这似乎正是我想要的,但遗憾的是(可能是因为我对连接的理解不好)仍然没有返回我想要的。根据下表
菜单
然后是PagesInMenu的联接表(带有WHERE PageID=1的WHERE子句)
我们可以看到,id为1的页面未在菜单5和6中引用。我希望相关查询只返回一行,即ID为5的菜单的ID、名称和说明,因为这是唯一一个第1页未包含且可编辑的菜单
相反,新查询返回
我已经划掉了所有返回但不应该返回的行。这是怎么回事 更新:
- 已删除
.CreateCriteria(“页面”)
- 添加子查询
var querymenuItemswithPage = DetachedCriteria.For<Menu>() .CreateCriteria("Pages") .Add(Restrictions.Eq("ID", pageId)) .SetProjection(Projections.Id()) // Only retrieve the required properties from Menu object ProjectionList menuViewProjections = Projections.ProjectionList() .Add(Projections.Property("ID"), "ID") .Add(Projections.Property("Name"), "Name") .Add(Projections.Property("Description"), "Description"); var menus = session.CreateCriteria(typeof(Menu)) // Only menu's that are editable .Add(Restrictions.Eq("IsEditable", true)) // Only project required properties .SetProjection(menuViewProjections) // Only retrieve menus that do NOT contain this referenced page .Add(Subqueries.PropertyNotIn("Id", querymenuItemswithPage)) // Transform results into required view objects .SetResultTransformer(Transformers.AliasToBean(typeof(MenuView))) .List<MenuView>();
var querynumitemswithpage=DetachedCriteria.For() .CreateCriteria(“页面”) .Add(Restrictions.Eq(“ID”,pageId)) .SetProjection(Projections.Id()) //仅从菜单对象检索所需的属性 ProjectionList菜单视图投影=投影。ProjectionList() .Add(Projections.Property(“ID”),“ID”) .Add(Projections.Property(“名称”),“名称”) .添加(投影、属性(“说明”)、“说明”); var menus=session.CreateCriteria(菜单类型)) //只有可编辑的菜单 .Add(Restrictions.Eq(“IsEditable”,true)) //仅项目所需的属性 .SetProjection(菜单视图投影) //仅检索不包含此引用页面的菜单 .Add(subquerys.PropertyNotIn(“Id”,querynumitemswithpage)) //将结果转换为所需的视图对象 .SetResultTransformer(Transformers.AliasToBean(typeof(MenuView))) .List();
SELECT this_.ID as y0_,
this_.Name as y1_,
this_.Description as y2_
FROM [Menu] this_
inner join PagesInMenu pages3_
on this_.ID = pages3_.MenuID
inner join [Page] page1_
on pages3_.PageID = page1_.ID
WHERE this_.IsEditable = 1 /* @p0 */
and not (page1_.ID = 8 /* @p1 */)
// Only retrieve menus that do NOT contain this referenced page
.CreateCriteria("Pages")
.Add(Subqueries.PropertyNotIn("Id", querymenuItemswithPage)) <--- query you have would be here
SELECT this_.ID as y0_,
this_.Name as y1_,
this_.Description as y2_
FROM [Menu] this_
inner join PagesInMenu pages3_
on this_.ID = pages3_.MenuID
inner join [Page] page1_
on pages3_.PageID = page1_.ID
WHERE this_.IsEditable = 1 /* @p0 */
and page1_.ID not in (SELECT this_0_.ID as y0_
FROM [Page] this_0_
WHERE this_0_.ID = 1 /* @p1 */
var querymenuItemswithPage = DetachedCriteria.For<Menu>()
.CreateCriteria("Pages")
.Add(Restrictions.Eq("ID", pageId))
.SetProjection(Projections.Id())
// Only retrieve the required properties from Menu object
ProjectionList menuViewProjections = Projections.ProjectionList()
.Add(Projections.Property("ID"), "ID")
.Add(Projections.Property("Name"), "Name")
.Add(Projections.Property("Description"), "Description");
var menus = session.CreateCriteria(typeof(Menu))
// Only menu's that are editable
.Add(Restrictions.Eq("IsEditable", true))
// Only project required properties
.SetProjection(menuViewProjections)
// Only retrieve menus that do NOT contain this referenced page
.Add(Subqueries.PropertyNotIn("Id", querymenuItemswithPage))
// Transform results into required view objects
.SetResultTransformer(Transformers.AliasToBean(typeof(MenuView)))
.List<MenuView>();