我正在编写这个论坛,因为我是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)
谢谢...
答案 0 :(得分:2)
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 :(得分:1)
如果您使用成员身份并且您不想在dbml中包含aspnet_Users,则显示用户名:
...
LastPostUserId = posts.OrderByDescending(p=>p.PostId).Take(1).Select(p=> Membership.GetUser(p.UserId))
...
使发布的样本更好一点的另一个变化是在posts变量中添加orderbydescending: 然后你可以从select子句中删除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)为null,它可能会抛出错误。
答案 2 :(得分:0)
这几乎可以解决问题(虽然它会产生一些可怕的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 ...怎么能这样做?您将如何优化整个查询?