【问题标题】:How do I create this query using NHibernate Criteria如何使用 NHibernate Criteria 创建此查询
【发布时间】:2026-01-05 22:35:01
【问题描述】:

我是 NHibernate 的新手,我无法找出使用 NHibernate 的 Criteria 引擎来表示某些 SQL 的最佳方式。下面是对象模型的基本描述:

public class Project : EntityBase<Project>
{
    // Properties for a project
    public virtual Company OwnerCompany { get; set; }
    public virtual IList<UserAssignment> UserAssignments { get; set; }
}

public class Company : EntityBase<Company>
{
    // Properties for a company
}

public class User : EntityBase<User>
{
    // Properties for a user
    public virtual Company Company { get; set; }
}

public class UserAssignment : EntityBase<UserAssignment>
{
    // Properties for an assignment
    public virtual User User { get; set; }
}

您可以从类中推断出底层表的样子,所有 NH 的东西都在 EntityBase 抽象类中。

本质上,我想提取特定公司拥有的所有项目,或者为该公司的某个人提供 UserAssignments。 以下是我在 SQL 中的操作方式:

select P.*
from Project P
where P.OwnerCompany_Id = @CompanyId
    or P.Id in (
        select Project_Id
        from UserAssignment UA
            join User U on UA.User_Id = U.Id
        where U.Company_Id = @CompanyId
    )

我正在使用 DetachedCriteria,我什至无法让它工作,只是将 UserAssignment 的用户与公司相匹配,更不用说分配和所有者了。当我尝试这个时:

var criteria = DetachedCriteria
                .For<Project>()
                .CreateCriteria("UserAssignments")
                    .Add(Expression.Eq("User.Company.Id", requestingUser.Company.Id));

我收到一条错误消息,提示“无法解析属性:TestProject.Domain.UserAssignment 的 User.Company.Id。”

谁能帮忙?

【问题讨论】:

    标签: nhibernate nhibernate-criteria


    【解决方案1】:

    使用 Criteria 时,您无法使用表达式进行导航。您需要明确指定别名:

    .CreateAlias("User", "User")
    .Add(Expression.Eq("User.Company", requestingUser.Company));
    

    【讨论】:

      【解决方案2】:

      我最终不得不使用这样的子查询:

      var userSubquery = DetachedCriteria.For<UserAssignment>()
          .SetProjection(Projections.Property("Project")) // I had to put this reference property in the UserAssignment
          .CreateCriteria("User")
          .CreateCriteria("Company")
          .Add(Restrictions.Eq("Id", requestingUser.Company.Id));
      
      var projectCriteria = DetachedCriteria.For<Project>()
          .Add(Restrictions.Or(
              Restrictions.Eq("OwnerCompany.Id", requestingUser.Company.Id),
              Subqueries.PropertyIn("Id", userSubquery)));
      

      我想避免将Project 属性添加到UserAssignment 对象,因为该对象可以应用于项目以外的其他一些东西,但我不知道如何在没有它的情况下使用条件强制连接。我不想使用 SQL 表达式或 HQL。

      乔什

      【讨论】: