OK、まず私の単純なドメイン モデルは、1 対多の関係を持つ 2 つのクラスであり、単純な親 -> 子の関係です。「ツイート」には 1 つ以上の「投票」がありますが、各投票は 1 つのツイートにのみ属します。
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 のいずれかでクエリを作成しようとしていますが、選択する 2 つの列も追加します。
- 投票数のカウントと...
- 特定の TwitterUserId に基づいて、特定のユーザーがそのツイートに投票したかどうか
2 つの列が追加されたので、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 v2 用に構築された NHibernate LINQ プロバイダーを使用して、NHibernate で上記の LINQ クエリを実行しようとしました。
var tweets = from t in Session.Linq<Tweet>()
where (snip)
しかし、うまくいきませんでした。Nhibernate 3.0 での LINQ サポートは改善されましたか? バージョン 3.0 はまだアルファ版なので使うのは少し気が進まないのですが、これでうまくいくならやってみようと思います。
更新 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);