2016-09-19 6 views
0

Ich bin neu in Datenbanken und EF. Ich verwende EF in einem ASP.NET Core MVC-Projekt. Der folgende Implementierungscode stammt von einem Controller, mit dem Ziel, Daten aus zwei Tabellen zu einer Zusammenfassung zusammenzufassen.DB erste Entity Framework Abfrage unglaublich langsam

Die Datenbank hat Tabellen: Batch, Doc.

Batch enthält viele Spalten, einschließlich: int BatchId, String BatchEnd. BatchEnd ist eine konsistent formatierte DateTime, z. 23/09/2016 14:33:21

Doc hat viele Spalten einschließlich: String BatchId, String HardCopyDestination. Viele Dokumente können auf dieselbe BatchId verweisen, aber alle Dokumente, die dies tun, haben denselben Wert für HardCopyDestination.

Ich möchte folgende Ansichtsmodell

public class Batch 
{ 
    public int BatchId { get; set; } 
    public string Time { get; set; } // from BatchEnd 
    public string HardCopyDestination { get; set; } 
} 

Aber meine aktuelle Abfrage zu füllen, unten, ist Hund läuft langsam. Habe ich das richtig umgesetzt?

var BatchViewModels = new List<Batch>(); 

// this is fine 
var batches = _context.BatchTable.Where(
        b => b.BatchEnd.Contains( 
         DateTime.Now.Date.ToString("dd/MM/yyyy"))); 


// this bit disappears down a hole 
foreach (var batch in batches) 
{ 
    var doc = _context.DocTable.FirstOrDefault(
        d => d.BatchId == batch.BatchId.ToString()); 

    if (doc != null) 
    { 
     var newBatchVM = new Batch 
     { 
      BatchId = batch.BatchId, 
      Time = batch.BatchEnd.Substring(whatever to get time), 
      HardCopyDestination = doc.HardCopyDestination 
     }; 

     BatchViewModels.Add(newBatchVM); 
     continue; 
    } 
} 

return View(BatchViewModels); 
+2

Warum verwenden Sie Zeichenfolgen zur Darstellung von DateTime-Instanzen? Sie sollten 'System.DateTime' in .net (C#) und' DateTime2 (7) 'oder' DateTime' in Sql Server verwenden (* Sie haben Ihren Datenbankserver nie erwähnt, wenn er nicht sql verwendet, dann den Servertyp zur Darstellung verwendet Datum mal, aber es wird keine Zeichenfolge sein) *. Auch die Formatierung eines Datums (TT/MM/JJJJ oder MM/TT/JJJJ oder was auch immer) ist eine Lösung für die Darstellungsschicht und sollte niemals auf die Persistenzschicht übertragen werden. – Igor

+0

Sie machen einige komische Sachen mit Ihren Daten – KSib

+0

@Igor die Datenbank ist außerhalb meines Einflussbereichs entworfen und bevölkert. Ich kann jedoch mein eigenes ViewModel beeinflussen, also ja, weniger fummelig, es einfach vollständig zu parsen und dann nur das Zeitelement anzuzeigen. –

Antwort

0

Ich denke, Sie schlagen die Datenbank einmal pro Batch. Wenn Sie viele Chargen haben, ist das teuer. Sie können alle Dokumente auf einmal von db erhalten.

var batchDict = batches.ToDictionary(b => b.BatchId); 
var documents = _context.DocTable.Where(doc => batchDict.Keys.Contains(doc.BatchId)); 
BatchViewModels.AddRange(documents.Select(d => new Batch 
{ 
    BatchId = d.BatchId, 
    Time = batchDict[d.BatchId].BatchEnd.TimeOfDay, // you only want the time? 
    HardCopyDestination = d.HardCopyDestination 
}); 

By the way, ist Igor rechts über Termine und zusätzlich, wenn BatchID int in BatchTable ist, dann sollte es das auch in DocTable sein. In obigem Code gehe ich davon aus, dass sie vom selben Typ sind, aber nicht so schwer zu ändern sein sollten, wenn sie es nicht sind.

Igor hat auch recht über Profiling db ist ein guter Weg, um zu sehen, was das Problem ist. Ich nehme nur eine Schätzung basierend auf Ihrem Code.