好的,首先我的简单域模型是 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 v2 构建的 NHibernate LINQ 提供程序在 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);