LINQ запрос для форума
Вопрос
<Р> Я кодирующая этот форум и так как я новичок в LINQ я столкнулся с этой проблемой, когда пользователь нажимает на главной странице. Я хочу, чтобы таблица отображения списка форумов, как это:
Forum --- Topics (count) --- Posts (count) --- LastPostUserId --- LastPostTime
<Р> У меня есть следующие таблицы SQL:
Forums:
ForumId (int32),
Title (string),
Description (string)
ForumThreads:
ThreadId (int32),
ForumId (int32),
UserId (guid),
Subject (string),
Views (int32),
CreateDate (DateTime)
ForumPosts:
PostId (int32),
ThreadId (int32),
UserId (guid),
Post (string),
CreateDate (datetime)
<Р> Спасибо ... Решение
<Р> Для отображения имени пользователя, если вы используете членство, и вы не хотите, чтобы включить aspnet_Users в вашем DBML:
...
LastPostUserId = posts.OrderByDescending(p=>p.PostId).Take(1).Select(p=> Membership.GetUser(p.UserId))
...
<Р> Еще одно изменения, чтобы сделать ваш отправили образец немного лучше, чтобы добавить OrderByDescending в постах переменных:
Тогда вы можете уронить 4 раз повторил OrderByDescending от выбора пункта:
from forum in Forums
let posts = ForumPosts.Where(p => p.ForumThreads.ForumId.Equals(forum.ForumId)).OrderByDescending(p=>p.PostId)
select new
{
Forum = forum.Title,
Description = forum.Description,
Topics = forum.ForumThreads.Count(),
Posts = posts.Count(),
LastPostId = posts.Take(1).Select(p=>p.PostId),
LastPostThreadId = posts.Take(1).Select(p=>p.ThreadId),
LastPostUserId = posts.Take(1).Select(p=>p.UserId),
LastPostTime = posts.Take(1).Select(p=>p.CreateDate)
}
<Р> Или еще чище:
from forum in Forums
let posts = ForumPosts.Where(p => p.ForumThreads.ForumId.Equals(forum.ForumId))
let lastPost = posts.OrderByDescending(p=>p.PostId).Take(1)
select new
{
Forum = forum.Title,
Description = forum.Description,
Topics = forum.ForumThreads.Count(),
Posts = posts.Count(),
LastPostId = lastPost.PostId,
LastPostThreadId = lastPost.ThreadId,
LastPostUserId = lastPost.UserId,
LastPostUserName = Membership.GetUser(lastPost.UserId),
LastPostTime = lastPost.CreateDate
}
<Р> Проверьте этот код, когда нет последних сообщений Тхо, я думаю, что это может бросить ошибку, если Take (1) равно нулю .. Другие советы
from forum in forums
from posts in db.ForumPosts.Where(p => p.Thread.ForumId.Equals(forum.ForumId))
select new
{
Forum = forum.Title,
Topics = forum.ForumThreads.Count(),
Posts = posts.Count(),
LastPostBy = posts.OrderByDescending(p => p.CreateDate).FirstOrDefault(p => p.UserId),
LastPostTime= posts.Max(p => p.CreateDate))
}
<Р> непроверенных конечно, но попробуйте начать отсюда и проверить SQL запрос (ы) он выполняет и дайте мне знать, если он нуждается в оптимизации.
<Р> Это почти делает трюк (хотя он генерирует некоторый ужасный SQL; -) ...)
from forum in Forums
let posts = ForumPosts.Where(p => p.ForumThreads.ForumId.Equals(forum.ForumId))
select new
{
Forum = forum.Title,
Description = forum.Description,
Topics = forum.ForumThreads.Count(),
Posts = posts.Count(),
LastPostId = posts.OrderByDescending(p=>p.PostId).Take(1).Select(p=>p.PostId),
LastPostThreadId = posts.OrderByDescending(p=>p.PostId).Take(1).Select(p=>p.ThreadId),
LastPostUserId = posts.OrderByDescending(p=>p.PostId).Take(1).Select(p=>p.UserId),
LastPostTime = posts.OrderByDescending(p=>p.PostId).Take(1).Select(p=>p.CreateDate)
}
<Р> Последней вещи - у меня есть отношения с «ForumPosts» таблицы SQL для «Aspnet_Users», и я хотел бы, чтобы отобразить столбец Aspnet_Users.UserName в LastPostUserName ... как это может быть сделано? И как бы вы оптимизировать весь запрос? Не связан с StackOverflow