NHibernate - 如何编写此查询:选择父母&找到符合条件的每个父母的孩子

时间:2010-09-15 13:34:08

标签: nhibernate hql linq-to-nhibernate nhibernate-criteria

好的,首先我的简单域模型是2个具有一对多关系的类,一个简单的父 - >孩子的关系。 '推文'有一个或多个'投票',但每个投票只属于一个推文等。

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域对象,并且可能需要运行Report查询,这没关系。但我正在努力弄清楚如何编写这个查询。

我知道如何将其写为存储过程,或使用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:感谢Diego Mijelshon的建议,我升级到NHibernate 3.0 alpha 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);

1 个答案:

答案 0 :(得分:2)

与NHibernate 3完全相同;只需将dataContext.Tweets替换为session.Query<Tweet>

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