C # Komplexe Linq – Verbinde zwei Tabellen innerhalb einer Unterabfrage

Ich arbeite derzeit an einem System, das eine sehr komplexe database verwendet.

Ich muss Informationen aus mehreren Tabellen und Assoziationen zusammenstellen, um eine solche list anzuzeigen (ich habe viele davon):

[List] (Class `List`) [Id] [EntityId] [Name] [Description] [Users] (From `List<User> List.AssignedUsers` joined to `List<ListMember> List.Members`) [Id] [EntityId] [Username] [FullName] [Email] [ListId] [Order] (From `ListOrder` property in `ListMember` object) [Status] (From `Status` property in `ListMember` object) [Id] [NameEn] [NameFr] [Color] [Type] [Tag] [Options] 

In diesem ist List.AssignedUsers die list der Benutzer, die auf die list zugreifen können. List.Members ist die list der aktuell aktiven Benutzer in der list, die ihren Status enthält. Wenn ein AssignedUser nicht in Members , muss die Status und Order Eigenschaft null sein.

Hier ist, wie die DB entworfen ist:

DB-Diagramm

Hier ist der Code, den ich versuche zu verwenden:

 var lists = await (from l in db.Lists.Include("Members").Include("AssignedUsers") where l.DateDeleted == null select new ListModel { Id = l.Id, EntityId = l.EntityId, Name = l.Name, Description = l.Description, Users = ( from u in l.AssignedUsers join lms in l.Members on u.Id equals lms.UserId into members from lm in members.DefaultIfEmpty() select new UserModel { Id = u.Id, EntityId = u.EntityId, Username = u.Username, FullName = u.FullName, Email = u.Email, ListId = l.Id, Order = (lm == null ? lm.ListOrder : -1), Status = (lm != null ? new StatusModel { Id = lm.Status.Id, Type = lm.Status.Type, Color = lm.Status.Color, Tag = lm.Status.Tag, NameEn = lm.Status.NameEn, NameFr = lm.Status.NameFr, Options = lm.Status.AvailableOptions } : null) } ).ToList() }).ToListAsync(); return lists; 

Das Problem ist, dass diese Abfrage sehr langsam ist, und anstatt ein Ergebnis zurückzugeben, w3wp.exe mein w3wp.exe process mit einem schönen windows, das mir sagt, dass .NET abgestürzt ist. Das Fehlerprotokoll sagt nichts als das:

 Faulting application name: w3wp.exe, version: 10.0.10240.16384, time stamp: 0x559f3dad Faulting module name: ntdll.dll, version: 10.0.10240.16430, time stamp: 0x55c599e1 Exception code: 0xc00000fd Fault offset: 0x0003dcb9 Faulting process id: 0x4998 Faulting application start time: 0x01d1134884f4b8dd Faulting application path: C:\Windows\SysWOW64\inetsrv\w3wp.exe Faulting module path: C:\Windows\SYSTEM32\ntdll.dll Report Id: 52069c20-912c-428a-b4fc-271851dbaba0 Faulting package full name: Faulting package-relative application ID: 

Jetzt habe ich versucht, einige andere Möglichkeiten, aber ich bin auf der search nach der leistungsstärksten, und wenn LINQ kann es nicht tun, werde ich es in SQL direkt zu tun!

Es ist langsam, weil du die Bibliothek daran ToList , eine einzelne Abfrage zu verwenden, weil du verschachtelte ToList Anrufe ToList .

Wenn du stattdessen nur eine nette Beschreibung deines objects ToArray dich und alle an und rief ToArray (warum list?) Am Ende, es wäre gut, aber dein path ruft den ersten Teil der Abfrage am Anfang an für jedes Element zurückgegeben ruft die Unterabfrage, um die Ergebnisse zu füllen.

Warum es stürzt, ist es der gleich gut geschriebene Zustand: lm == null ? lm.ListOrder : -1 lm == null ? lm.ListOrder : -1 – und man konnte es einfach sehen, indem man einfach den process debugging.