在 Linq to NHibernate 中测试条件的最佳方法是什么?

发布于 2024-12-28 09:57:27 字数 1719 浏览 3 评论 0原文

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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

下雨或天晴 2025-01-04 09:57:27

这很有趣,但你尝试过吗:

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

我认为从你当前的选择来看,它会更快。事实上,它不会检查所有项目(例如计数),也不会获取所有数据。

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.

゛清羽墨安 2025-01-04 09:57:27

像这样的事情应该创建一个仅包含单个列的查询:

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

投影到匿名类型允许 NHibernate 仅获取指定的列(例如 ID)。

但当需要检索大量行时,它通常更合适。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文