LINQ запрос для форума - PullRequest
3 голосов
/ 31 мая 2009

Я кодирую этот форум и, поскольку я новичок в 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)

Спасибо ...

Ответы [ 3 ]

2 голосов
/ 31 мая 2009
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-запросы, которые он выполняет, и дайте мне знать, если нужно оптимизировать.

1 голос
/ 31 мая 2009

Для отображения имени пользователя, если вы используете членство и не хотите включать aspnet_Users в свой dbml:

...
LastPostUserId = posts.OrderByDescending(p=>p.PostId).Take(1).Select(p=> Membership.GetUser(p.UserId))
...

Еще одно изменение для улучшения качества размещенного вами образца - добавление orderbydescending в переменную posts: Затем вы можете удалить 4 раза повторяющийся OrderByDescending из предложения select:

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) равно нулю

0 голосов
/ 31 мая 2009

Это почти сработало (хотя и генерирует ужасный 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)
}

И последнее: у меня есть отношение из таблицы SQL «ForumPosts» к «Aspnet_Users», и я хотел бы отобразить столбец Aspnet_Users.UserName как LastPostUserName ... как это можно сделать? А как бы вы оптимизировали весь запрос?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...