Pregunta

Estoy codificación de este foro y ya que soy nuevo en LINQ me encontré con este problema cuando el usuario pulsa la página principal. Quiero una tabla que muestra una lista de los foros de la siguiente manera:

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

Tengo las siguientes tablas 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)

Gracias ...

¿Fue útil?

Solución

Para mostrar el nombre del usuario si utiliza la pertenencia y no desea incluir los aspnet_Users en su dbml:

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

Otro cambio para hacer su muestra publicado un poco mejor es añadir el orderbydescending en los puestos variables: A continuación, puede soltar los 4 veces OrderByDescending repetida de la 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)
}

O incluso más limpio:

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
}

Pruebe este código cuando no hay últimos mensajes Tho, creo que podría producir un error si Take (1) es nula ..

Otros consejos

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

no probado por supuesto, pero trata de empezar desde aquí y comprobar la consulta SQL (s) que se ejecuta y que me haga saber si necesita optimización.

Esto casi hace el truco (aunque genera cierta SQL horribles; -) ...)

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

Lo último - Tengo una relación de 'ForumPosts' tabla de SQL a 'Aspnet_Users' y me gustaría mostrar la columna Aspnet_Users.UserName como LastPostUserName ... ¿cómo se puede hacer esto? Y cómo optimizar la consulta entera?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top