Хорошо, сначала моя простая модель предметной области - это 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, и, вероятно, потребуется выполнить запрос отчета, это нормально. Но я изо всех сил пытаюсь понять, как написать этот запрос.
Я знаю, как написать это как хранимую процедуру или используя 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.
Обновление: Я попытался выполнить указанный выше запрос LINQ в NHibernate с помощью поставщика NHibernate LINQ, созданного для NHibernate v2 , например:
var tweets = from t in Session.Linq<Tweet>()
where (snip)
Но это не сработало. Улучшена ли поддержка LINQ в Nhibernate 3.0? Я немного неохотно пользуюсь версией 3.0, потому что она все еще альфа, но если это сработает, то я могу попробовать.
Обновление 2: Благодаря предложению Диего Миджелсона я обновился до 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);