代码之家  ›  专栏  ›  技术社区  ›  Emidee

NHibernate查询和预期结果之间的结果不一致

  •  0
  • Emidee  · 技术社区  · 16 年前

    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));
    

    我有三排,这是我应该有的。

    为什么我的结果不同?

    迈克

    2 回复  |  直到 16 年前
        1
  •  0
  •   rebelliard    16 年前

    我注意到,有时日志记录的SQL与实际用于数据库的SQL并不完全相同。上一次我遇到这个问题时,是一个裁剪Id值的问题,例如,生成的SQL有类似 and team3_.Id=2 ,所使用的SQL实际上 and team3_.Id='2 ' (或者也许, player_0.Sex='Male ' ),这总是失败的。

    我建议你试试这个HQL:

    string hql = @"from Player p where p.Sex = 'Male' 
                    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 = 2)";
    return Session.CreateQuery(hql).Enumerable<Player>();
    

    如果可以的话,您需要检查值中是否有多余的空格。

        2
  •  0
  •   Emidee    16 年前

    我把我的问题改成这样:

    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之后,我有了使用“notexists”的想法,这给了我一些提示。

    如果你问我为什么不保留LINQ,那是因为目前我将实体之间的关系隐藏为私有字段,以迫使实体的用户使用与它们关联的helper函数。但错误的是,在大多数情况下,这禁止我在我的存储库中使用LINQ。

    但我想知道这样做是否更好地“隐藏”我的关系并将它们作为公共属性公开,但保留我的助手函数。这将允许我在查询中使用LINQ。

    你在使用NH的应用程序中做什么?

    您认为这是一个可以接受的折衷方案,以维护简单的映射和查询(使用LINQ),但如果用户不使用保持关系的helper函数,则可能会导致实体的误用?

    推荐文章