2010-12-14 14 views
1

ich den folgenden Code geschrieben haben:Linq-Anweisungen müssen die Optimierung

//get the user from the DB 
var tmpuser = _db.aspnet_Users.First(q => q.UserName == user.Identity.Name); 

//list the direct connections to Verbond 
List<Verbond> verb1 = tmpuser.UsersVerbondens 
          .Where(q => q.Schooljaar.Sch_Schooljaar == schooljaarparam) 
          .Select(q => q.Verbond) 
          .ToList(); 

//list the connected Facturatieverbonden 
List<FacturatieVerbonden> verb2 = tmpuser.UsersFacturatieVerbondens 
             .Where(q => q.Schooljaar.Sch_Schooljaar == schooljaarparam) 
             .Select(q => q.FacturatieVerbonden) 
             .ToList(); 

//loop through the facturatieverbonden and add their verbonds to the first list 
foreach (FacturatieVerbonden v in verb2) { 
    verb1.AddRange(v.Verbonds); 
} 

//make a distinct list 
List<Verbond> test = verb1.Distinct().ToList(); 

So können Nutzer auf 0 oder mehr facturatieverbonden und auch verbunden werden können, um verbond angeschlossen werden.

Ein facturatieverbonden kann einen oder mehrere verbond unter sich haben.

Was ich brauche ist eine Liste aller verbond 's der Benutzer ist verbunden, direkt oder indirekt über die facturatieverbonden.

Mein Code funktioniert, aber ich denke nicht, dass es sehr effizient ist. Irgendwelche Hinweise, um es sauberer zu machen?

Antwort

5

Ihre Abfrage ist nicht sehr LINQy. Hier ist eine mögliche Verbesserung:

  //list the direct connections to Verbond 
var test = (from q in tmpuser.UsersVerbondens 
      where q.Schooljaar.Sch_Schooljaar == schooljaarparam 
      select q.Verbond) 
      //return distinct values 
      .Union 
      //list the connected Facturatieverbonden 
      (from q in tmpuser.UsersFacturatieVerbondens 
      where q.Schooljaar.Sch_Schooljaar == schooljaarparam 
      from v in q.FacturatieVerbonden.Verbonds 
      select v) 
      //return a List 
      .ToList(); 

von ToList macht das allerletzte, was es tut, die ganze Berechnung kann in der Datenbank durchgeführt werden, die Vermeidung aller Zwischenlisten.

+0

Gute Idee, aber kleines Problem: q.Verbond und vf.Verbonds (Plural) sind verschiedene Arten. –

+0

David B: Das ist das Problem mit der Programmierung in einer fremden Sprache - es ist schwer zu sagen, wenn etwas nicht sinnvoll ist. Habe ich es gerade jetzt? – Gabe

+0

funktioniert hervorragend !!! :) – Stefanvds

0

Ihr Leistungsproblem ist hier. Jeder AddRange-Aufruf zählt v.Verbonds auf, und jeder ist ein Datenbank-Roundtrip.

//loop through the facturatieverbonden and add their verbonds to the first list 
foreach (FacturatieVerbonden v in verb2) { 
    verb1.AddRange(v.Verbonds); 
} 

es zu beheben:

//query the connected Facturatieverbonden 
IQueryable<FacturatieVerbonden> verbQuery2 = tmpuser.UsersFacturatieVerbondens 
    .Where(q => q.Schooljaar.Sch_Schooljaar == schooljaarparam) 
    .Select(q => q.FacturatieVerbonden); 

verb1.AddRange(verbQuery2.SelectMany(fv => fv.Verbonds)); 

Es gibt immer noch die Leistung zu straffen genug Platz ist, aber zumindest diese Adresse des Brutto Problem. Sie könnten leicht eine 10-fache Beschleunigung beobachten.