Pergunta

Eu estou codificação neste fórum e desde que eu sou novo para LINQ Corri para este problema quando o usuário pressiona a página principal. Eu quero uma tabela que exibe uma lista de fóruns como este:

Forum  --- Topics (count) --- Posts (count) --- LastPostUserId --- LastPostTime

Eu tenho as seguintes tabelas 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)

Obrigado ...

Foi útil?

Solução

Para exibir o nome do usuário se você usar a associação e você não quer incluir os aspnet_Users em seu dbml:

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

Outra mudança para tornar a sua amostra colocaram um pouco melhor é adicionar o OrderByDescending na variável de mensagens: Depois, você pode soltar os 4 vezes OrderByDescending repetida da cláusula 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)
}

Ou ainda mais limpa:

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
}

Test este código quando não existem últimas mensagens Tho, eu acho que pode lançar um erro se Faz (1) é nulo ..

Outras dicas

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))
}

ofcourse não foi testado, mas tente começar por aqui e confira a consulta SQL (s) ele executa e deixe-me saber se ele precisa de otimização.

Esta quase faz o truque (embora ele gera alguns SQL horrível; -) ...)

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)
}

A última coisa - eu tenho uma relação da tabela SQL 'ForumPosts' para 'Aspnet_Users' e eu gostaria de exibir a coluna Aspnet_Users.UserName como LastPostUserName ... como isso pode ser feito? E como você otimizar a consulta inteira?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top