简体   繁体   中英

What is the best way to test a condition in Linq to NHibernate?

The Any() linq function seems to load all of the entity's columns even though they're not needed.

The following code:

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

Generates the following 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 */

However, the following code:

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

Generates the following sql, which is what is expected:

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 */

The Count() method does what is expected, but it is a bit less straightforward.

Is the Any() behavior considered normal or is it a bug? It doesn't seem optimal to me, but maybe loading the entity isn't really slower than asking SQL to return the count?

In light of this, what is considered to be the best way to test a condition in Linq to NHibernate?

It was interesting but did you tryed:

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

I think it would be faster from your current options. In fact it doesn't checks for all items (like count) Also it doesn't fetch all data.

Something like this should create a query with only a single column:

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

Projection to an anonymous type allows NHibernate to fetch only the specified column (ID, for example).

But it is usually more suitable when there is a significant number of rows to retrieve.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM