我在HQL中有以下查询:
public IEnumerable<Player> PlayersNotInTeam(Team team)
{
return Session.CreateQuery("from Player p where p.Sex = :teamSex and p.Visible and p.Id not in (select pit.Player from PlayerInTeam as pit join pit.Roster as roster join roster.Team as team where team = :teamId)")
.SetParameter("teamId", team.Id)
.SetParameter("teamSex", team.Sex)
.Enumerable<Player>();
}
当我使用NHibernate运行此查询时,它将返回2行。
如果我在数据库浏览器(SQLite Explorer)中运行NH生成的SQL脚本:
select player0_.Id as Id26_, player0_.Sex as Sex26_, player0_.FirstName as FirstName26_, player0_.LastName as LastName26_, player0_.DefaultNumber as DefaultN5_26_, player0_.Visible as Visible26_, player0_.DefaultPosition_id as DefaultP7_26_
from Players player0_
where player0_.Sex='Male'
and player0_.Visible=1
and (player0_.Id not in
(select playerinte1_.Player_id
from "PlayerInTeam" playerinte1_
inner join "Roster" roster2_ on playerinte1_.Roster_id=roster2_.Id
inner join Teams team3_ on roster2_.Team_id=team3_.Id,
Players player4_
where playerinte1_.Player_id=player4_.Id
and team3_.Id=2));
我有3行,这是我应该拥有的。
为什么我的结果不同?
提前致谢
麦克
答案 0 :(得分:0)
我注意到有时候记录的SQL与真正用于数据库的SQL不完全相同。我最后一次遇到这个问题时,修剪Id值是一个问题,例如,生成的SQL类似于and team3_.Id=2
,所使用的SQL实际上是and team3_.Id='2 '
(或许,{{ 1}}),总是会失败。
我建议你试试这个HQL:
player_0.Sex='Male '
如果可行,您需要检查您的值是否有空余空格。
答案 1 :(得分:0)
我改变了我的查询:
return Session.CreateQuery("from Player p where p.Sex = :teamSex and p.Visible and not exists (from PlayerInTeam pit where pit.Player = p and pit.Roster.Team = :teamId)")
.SetParameter("teamId", team.Id)
.SetParameter("teamSex", team.Sex)
.Enumerable<Player>();
它现在有效。在我改变映射后尝试使用LINQ时,我有了使用“not exists”的想法,这给了我一些提示。
如果你问为什么我不保留LINQ,那是因为目前我将我的实体之间的关系隐藏为私有字段,以强制实体的用户使用关联它们的辅助函数。但错误的是,在大多数情况下,禁止我在我的存储库中使用LINQ。
但是我想知道这是不是更好地“隐藏”我的关系并将它们作为公共属性公开,但保留我的帮助函数。这将允许我在查询中使用LINQ。
你在使用NH的应用程序中做了什么?
你认为这对于维护简单的映射和查询(使用LINQ)是可接受的权衡,但是如果用户不使用辅助函数那么可能会导致实体的一些潜在误用成本保持关系?