2016-06-01 15 views
0

Ich versuche, meine Entitäten mit nur einigen von ihnen Kind (eins) zu bekommen, aber meine Anfrage ist sehr langsam.EntityFramework mit linq ist langsam

Meine Klasse sind:

  • 'Schaltung': enthält Liste der 'Etape'
  • 'etape': enthält Liste der 'Frage'

ich meine Schaltung filtern möchten, mit einer Geoposition aus dem ersten Etape jeder Schaltung, und alle Circuit-Entities erhalten, die meinen Filtern entsprechen, aber nur mit dem ersten Etape meiner Schaltung. (Also das Etape meiner gefilterten Schaltung mit numEtape == 1). Ich möchte nur das erste Etape, weil es 10,20,30 .. Etapes pro Schaltung sein kann, um die Länge meiner Abfrage zu reduzieren.

Dies ist meine Abfrage jetzt und es kann sehr langsam sein mit nur 20 000 Schaltung zu filtern. (Aber mit X etape, die etape haben Y Fragen ..)

var x = db.circuit.Include("etape").Include("etape.question") 
    .Where(
     c => c.etape.Count() >= 2 && 
     c.enabled && 
     !circuitsAfficher.Contains(c.id) && 
     (
      c.etape.Where(e => e.numEtape == 1).FirstOrDefault().posLat > xbottom && 
      c.etape.Where(e => e.numEtape == 1).FirstOrDefault().posLat < xtop 
     ) && 
     (
      c.etape.Where(e => e.numEtape == 1).FirstOrDefault().posLong < yright && 
      c.etape.Where(e => e.numEtape == 1).FirstOrDefault().posLong > yleft 
     ) 
    ) 
    .Select(p => new 
     { 
      circuit = p, 
      etape = p.etape.Where(c => c.numEtape == 1) 
     }).ToList(); 

EDIT: Neuer Code dank @Ivan Stoev, Arbeits

listFiltred = db.circuit.AsNoTracking().Where(
       c => c.etape.Count() >= 2 && 
       c.enabled && 
       !circuitsAfficher.Contains(c.id) && 
       c.etape.Any(e => e.numEtape == 1 && 
       e.posLat > Xbottom && e.posLat < Xtop && 
       e.posLong < yright && e.posLong > Yleft))      
        .Select(p => new CircuitWithEtape 
        { 
         circ = p, 
         firstetape = p.etape.Where(c => c.numEtape == 1).FirstOrDefault() 
        }).ToList(); 

CircuitWithEtape Klasse:

public class CircuitWithEtape 
    { 
     public circuit circ { get; set; } 
     public etape firstetape { get; set; } 
    } 

Bei Dieser Punkt habe ich eine Liste der Schaltung, mit all seinen Etape in Paar mit seinem ersten Etape (firstape).

+2

die Verwendung von '.FirstOrDefault()' und 'Count()' wird sich hier wirklich wie du verletzt umgehen Sie die verzögerte Ausführung und laden Sie das gesamte Daten-Diagramm, um diese zu lösen !! –

+0

Ich kann die Verwendung von Count() löschen, aber wie kann ich meine Schaltung mit einer Bedingung auf ihre ersten Etape-Kinder filtern? – Furtiro

+0

Passt 'numEtape == 1' zu einem einzelnen Etape pro Schaltung? Oder kann es mehr als eins zusammenbringen? –

Antwort

1

können Sie ersetzen alle c.etape.Where(e => e.numEtape == 1).FirstOrDefault() basierten Bedingungen (die ich eine Unterabfrage für jede Bedingung erzeugen vermuten) mit einzelnen Any Basis Bedingung:

.Where(
    c => c.etape.Count() >= 2 && 
    c.enabled && 
    !circuitsAfficher.Contains(c.id) && 
    c.etape.Any(e => e.numEtape == 1 && 
     e.posLat > xbottom && e.posLat < xtop && 
     e.posLong < yright && e.posLong > yleft) 
) 

die einzelnen EXISTS (subquery) Zustand im Inneren der Hauptabfrage erzeugen sollte.

EDIT: in der letzten Abfrage der Suche kann die folgenden vielleicht noch besser:

listFiltred = 
    (from c in db.circuit.AsNoTracking() 
     .Where(c => c.etape.Count() >= 2 && 
      c.enabled && 
      !circuitsAfficher.Contains(c.id)) 
    from e in c.etape 
     .Where(e => e.numEtape == 1 && 
      e.posLat > Xbottom && e.posLat < Xtop && 
      e.posLong < yright && e.posLong > Yleft) 
    select new CircuitWithEtape 
    { 
     circ = c, 
     firstetape = e 
    }).ToList(); 
+1

Es scheint viel besser! Ich werde es heute Abend testen, wenn ich Zugang zu meinem Projekt habe, ich werde Sie in Kontakt halten, danke! – Furtiro

+0

Ist meine Verwendung Ihrer Antwort Ihrer Meinung nach besser? Ich benutze FirstOrDefault() .. – Furtiro

+0

Du meinst das 'Select' Teil? Sicher, Sie können verwenden, was auch immer Sie dort mögen, meine Antwort zielte nur auf die 'Where'-Klausel ab. –