Каков наилучший способ проверить состояние в Linq для NHibernate? - PullRequest
2 голосов
/ 21 января 2012

Кажется, что функция Any () linq загружает все столбцы объекта, даже если они не нужны.

Следующий код:

if(Session.Query<Project>().Any(p=>p.ID == projectID && p.ProjectOwner.Responsible == CurrentUserID))
    // Current user is the responsible for this project

Создает следующий SQL:

select TOP (1) project0_.ProjectID                          as ProjectID7_,
               project0_.DateCreated                        as DateCrea2_7_,
               project0_.Type                               as Type7_,
               project0_.ProjectOwner_FK                    as ProjectOy8_7_,
               project0_.Address_FK                         as Address9_7_,

**[Snip -- the statement selects all of Project's columns]**

from   [Project] project0_
       inner join [OrganizationProject] organizati1_
         on project0_.ProjectOwner_FK = organizati1_.OrganizationProjectID
where  project0_.ProjectID = 1 /* @p0 */
       and organizati1_.Responsible_FK = 1 /* @p1 */

Однако следующий код:

if(Context.Projects.Where(p=>p.ID == projectID && p.ProjectOwner.Responsible == CurrentUserID).Count() == 1)
    // Current user is the responsible for this project

Создает следующий sql, что и ожидается:

select cast(count(*) as INT) as col_0_0_
from   [Project] project0_
       inner join [OrganizationProject] organizati1_
         on project0_.ProjectOwner_FK = organizati1_.OrganizationProjectID
where  project0_.ProjectID = 1 /* @p0 */
       and organizati1_.Responsible_FK = 1 /* @p1 */

Метод Count () делает то, что ожидается, но он немного менее прост.

Поведение Any () считается нормальным или это ошибка? Это не кажется мне оптимальным, но, может быть, загрузка сущности на самом деле не медленнее, чем запрос SQL для возврата счетчика?

В свете этого, что считается лучшим способом проверки состояния в Linq для NHibernate?

Ответы [ 2 ]

0 голосов
/ 21 января 2012

Примерно так должно создаваться запрос только с одним столбцом:

if(Session
    .Query<Project>()
    .Where(p=>p.ID == projectID && p.ProjectOwner.Responsible == CurrentUserID)
    .Select(p=>new { pID = p.ID })
    .Any())
{
   ...
}

Проекция на анонимный тип позволяет NHibernate извлекать только указанный столбец (например, ID).

Но обычно это более удобно, когда нужно извлечь значительное количество строк.

0 голосов
/ 21 января 2012

Было интересно, но вы пробовали:

if(Session.Query<Project>()
   .FirstOrDefault(p=>p.ID == projectID 
                 && p.ProjectOwner.Responsible == CurrentUserID) != null)

Я думаю, что это будет быстрее от ваших текущих вариантов. На самом деле он не проверяет все элементы (например, количество). Также он не получает все данные.

...