2013-01-15 93 views
2

我有以下型号:问题与NHibernate QueryOver和子查询

public class User 
{ 
    public virtual int Id { get; set; } 
    public virtual string Username { get; set; } 
    public virtual string Password { get; set; } 
    public virtual string Email { get; set; } 
    public IList<SubmissionNote> Notes { get;set; } 
} 

public class SubmissionNote 
{ 
    public virtual Int64 Id { get; set; } 
    public virtual string Text { get; set; } 
    public virtual DateTime CreatedOn { get; set; } 
    public virtual User Creator { get; set; } 
    public virtual Submission BelongsTo { get; set; } 
} 

public class Submission 
{ 
    public virtual Int64 Id { get; set; } 
    public virtual DateTime HappenedOn { get; set; } 
    public virtual int StatusCode { get; set; } 
} 

我想编写一个将所有其最后一个音符被一些用户或用户的列表中输入的提交查询(通过鉴定他们的名字)。我将不胜感激您使用NHibernate QueryOver API构建此查询的帮助。我已经能够创建一个查询,使所有的音符最后如下:

SubmissionNote alias = null; 
var lastNote = session.QueryOver<SubmissionNote>() 
    .SelectList(list => list. 
     SelectGroup(x => x.BelongsTo).WithAlias(() => alias.BelongsTo). 
     SelectMax(x => x.CreatedOn).WithAlias(() => alias.CreatedOn). 
     Select(x => x.Creator).WithAlias(() => alias.Creator). 
     Select(x => x.Id).WithAlias(() => alias.Id). 
     Select(x => x.Text).WithAlias(() => alias.Text)) 
    .TransformUsing(Transformers.AliasToBean<SubmissionNote>()) 
    .List(); 

我可以使用指定查询作为子查询来产生所需要的结果呢?或者你建议另一种解决方案?

回答

3

我会尝试这样一个子查询(尽管未测试)

SubmissionNote subNoteAlias = null, subNoteAliasMax =null; 
User userAlias = null; 
String[] userNames = new[]{"John","Joe"}; 

var subquery = 
    QueryOver.Of(() => subNoteAliasMax) 
     .Where(subNote => subNote.BelongsTo.Id == subNoteAlias.BelongsTo.Id) 
     .Select(Projections.Max<SubmissionNote>(subNote => subNote.CreatedOn)); 

var result = session 
.QueryOver<SubmissionNote>(() => subNoteAlias) 
.WithSubquery.WhereProperty(subNote=>subNote.CreatedOn).Eq(subquery) 
.JoinQueryOver(
     subNote=>subNote.Creator 
     ,()=>userAlias 
     ,JoinType.InnerJoin 
     ,Restrictions.In(Projections.Property(() => userAlias.Username), userNames)) 
    .List(); 

生成的SQL查询将(非常)大致是这样的:

SELECT SubmissionNote.* 
    FROM SubmissionNote INNER JOIN User 
    ON SubmissionNote.creatorId = User.userId 
    AND User.userName in ('john','joe') 
    WHERE SubmissionNote.CreatedOn = (SELECT MAX(CreatedOn) FROM SubmissionNote snAlias  
    WHERE snAlias.SubmissionId = SubmissionNote.SubmissionId) 

希望这会有所帮助。子查询可能会返回一个日期而不是一个id。 LMK和我会看看。

+0

我试过查询,它似乎工作。我对你的查询感到不知所措,因为我的直觉告诉我,我将不得不使用一组来完成我的任务。你能解释一下你的查询逻辑吗? – Ikaso

+1

@Ikaso我用生成的SQL查询的草图更新了我的答案。也许你可以用一个中间的DTO来获得相同的结果来存储组的结果。我会对答案感兴趣 – jbl