Несовместимые результаты между запросом NHibernate и предполагаемыми результатами - PullRequest
0 голосов
/ 28 сентября 2010

У меня следующий запрос на 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 строки.

Если я запускаю сценарий SQL, сгенерированный NH вмой браузер базы данных (SQLite Explorer):

    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 строки, что и должно быть.

Почему мои результаты отличаются?

Заранее спасибо

Майк

Ответы [ 2 ]

0 голосов
/ 28 сентября 2010

Я изменил свой запрос следующим образом:

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, что подсказало мне.

Если вы спросите, почему я не сохраняю LINQ, это потому, что в настоящее время я скрываю отношения между своими сущностями как частные поля, чтобы заставить пользователей сущностей использовать вспомогательные функции, которые их связывают. Но неправильно то, что в большинстве случаев это запрещает мне использовать LINQ в моих репозиториях.

Но мне интересно, не лучше ли было бы "скрыть" мои отношения и выставить их как публичные свойства, но сохранить мои вспомогательные функции. Это позволило бы мне использовать LINQ в моих запросах.

Что вы делаете в своих приложениях, используя NH?

Считаете ли вы, что это будет приемлемым компромиссом для поддержки простых отображений и запросов (с использованием LINQ), но с ценой некоторых потенциальных злоупотреблений сущностями, если пользователь не использует вспомогательные функции, которые сохранить отношения?

0 голосов
/ 28 сентября 2010

Я заметил, что иногда зарегистрированный 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>();

Если это работает, вам нужно проверить, есть ли в ваших значениях свободные пробелы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...