Domanda

Sono codifica questo forum e siccome io sono nuovo a LINQ Mi sono imbattuto in questo problema quando l'utente preme la pagina principale. Voglio una tabella che visualizza un elenco di forum in questo modo:

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

Ho le seguenti tabelle 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)

Grazie ...

È stato utile?

Soluzione

Per visualizzare il nome dell'utente se si utilizza l'appartenenza e non si desidera includere le aspnet_Users nel dbml:

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

Un altro cambiamento per rendere il vostro campione inviato un po 'meglio è quello di aggiungere l'OrderByDescending nei messaggi variabili: Poi si può cadere le 4 volte ripetuto OrderByDescending dalla clausola 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 anche più pulito:

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
}

Prova questo codice quando non ci sono ultimi post Tho, penso che potrebbe gettare un errore se Take (1) è nullo ..

Altri suggerimenti

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

non testati naturalmente, ma cercare di partire da qui e controllare la query SQL (s) esegue e fatemi sapere se ha bisogno di ottimizzazione.

Questo fa quasi il trucco (anche se genera qualche orribile 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)
}

L'ultima cosa - ho un rapporto da 'ForumPosts' tabella SQL a 'Aspnet_Users' e vorrei per visualizzare la colonna Aspnet_Users.UserName come LastPostUserName ... come può essere fatto? E come è possibile ottimizzare l'intera query?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top