2011-04-20 61 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));