2011-04-20 60 views
1

我是新来的NHibernate,和我有麻烦找出代表使用NHibernate的标准引擎的一些SQL最好的方式来创建此查询。这里的对象模型的基本描述:我如何使用NHibernate标准

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”

任何人都可以帮忙吗?

回答

0

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

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。

乔希

1

当使用标准,不能导航使用表达式。您需要明确指定别名:

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