2010-09-28 2 views
0

У меня есть следующий запрос в HQL:Противоречивые результаты между NHibernate запросов и желаемых результатов

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 строки, которая является то, что я должен иметь.

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

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

Майк

ответ

0

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

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

+0

К сожалению, это не работает:/Я пробовал несколько комбинаций с кавычками без, но я не получаю правильных результатов ... – Mike

+0

Майк, не могли бы вы использовать LIKE% Male% вместо знак равно Просто чтобы убедиться, что NHibernate не слишком сообразителен? – rebelliard

+0

Пол - это перечисление. Я добавил соглашение в FluentNhibernate, которое хранит значение перечисления вместо имени. Итак, у меня есть Male = 0 и Female = 1. Но я все равно получаю те же результаты. Проблема не в этом, так как забытый игрок имеет тот же пол, что и два возвращенных игрока ... – Mike

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

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

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

Что вы делаете в своих приложениях с помощью NH?

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

Смежные вопросы