2010-09-15 25 views
1

好吧,首先,我的简单领域模型是2个具有一对多关系的类,一个简单的父 - >子关系。 A“分享Tweet”有一个或多个“投票”,但每张票属于只有一个鸣叫等NHibernate - 如何编写此查询:选择父母并为每个匹配条件的父母找到子女

public class Tweet 
{ 
    public virtual long Id { get; set; } 
    public virtual string Username { get; set; } 
    public virtual string Message { get; set; } 

    public virtual ISet<Vote> Votes { get; set; } 
} 

public class Vote 
{ 
    public virtual long Id { get; set; } 
    public virtual long TwitterUserId { get; set; } 
    public virtual DateTime VotedDate { get; set; } 

    public virtual Tweet Tweet { get; set; } 
} 

我试着写在任何HQL,或的ICriteria NHibernate的LINQ查询,选择所有推文,但也补充说,选择两列:

  • 投票数的计数,并...
  • 无论特定的用户投票为鸣叫,基于特定TwitterUserId

有了两个额外的列,我不希望收到Tweet域对象,并且可能需要运行报告查询,那没问题。但我正在努力弄清楚如何编写这个查询。

我知道如何将它写成存储过程或使用LINQ 2 SQL。如果有帮助,我会将其表示为LINQ to SQL查询。

long userId = 123; 

var tweets = from t in dataContext.Tweets 
      where t.Application == app 
      orderby t.PostedDate desc 
      select new TweetReport() 
      { 
       Id = t.Id, 
       Username = t.Username, 
       Message = t.Message, 
       TotalVotes = t.Votes.Count(), 
       HasVoted = t.Votes.Any(v => v.TwitterUserId == userId) 
      }; 

我知道这将在LINQ 2 SQL工作,并产生相当有效的T-SQL,但我无法弄清楚如何在NHibernate的写。


更新:我试图通过使用NHibernate LINQ provider built for NHibernate v2,如运行在NHibernate的上述LINQ查询:

var tweets = from t in Session.Linq<Tweet>() 
      where (snip) 

但没有奏效。 Nhibernate 3.0中的LINQ支持有所改进吗?我有点不情愿使用3.0版本,因为它仍然是alpha版本,但是如果这样会起作用,那么我可能会放弃它。


更新2:感谢迭戈Mijelshon的建议下,我升级到NHibernate的3.0阿尔法2并写在LINQ查询:

var tweets = from t in Session.Query<Tweet>() 
      where t.App == app 
      orderby t.PostedDate descending 
      select t; 

int totalRecords = tweets.Count(); 

var pagedTweets = (from t in tweets 
        select new TweetReport() 
        { 
         Id = t.Id, 
         TwitterId = t.TweetId, 
         Username = t.Username, 
         ProfileImageUrl = t.ImageUrl, 
         Message = t.Message, 
         DatePosted = t.PostedDate, 
         DeviceName = t.Device.Name, 
         DeviceUrl = t.Device.Url, 
         TotalVotes = t.Votes.Count(), 
         HasVoted = t.Votes.Any(v => v.TwitterUserId == userId) 
        }) 
        .Skip(startIndex) 
        .Take(recordsPerPage) 
        .ToList(); 

return new PagedList<TweetReport>(pagedTweets, 
    recordsPerPage, pageNumber, totalRecords); 

回答

2

这正是与NHibernate 3相同;只需用session.Query<Tweet>代替dataContext.Tweets即可。

或者,您可以创建一个上下文类,将session.Query<Tweet>作为IQueryable<Tweet> Tweets属性公开,然后代码将保持100%不变。

+0

我试着用旧的NHibernate LINQ提供程序(与NHibernate v2一起工作)提供,并且它不工作,抛出异常。我做了一些研究,NHibernate的LINQ提供者有一些限制,不支持诸如子选择之类的东西。我把它LINQ到NHibernate V3是大幅改善? – 2010-09-15 15:51:39

+1

是的,新的集成提供商支持更多的场景。我专门测试了上面的查询,并且工作正常。 – 2010-09-15 16:45:21

+0

真棒,它工作出色,谢谢! – 2010-09-16 01:41:15