2009-07-28 8 views
1

Ich habe eine LINQ-Abfrage, die eine Liste verschachtelter Objekte abruft.Gibt es eine Möglichkeit, diese LINQ-Abfrage neu zu schreiben, so dass sie nur eine SQL-Abfrage ausführt?

from c in ClientsRepository.LoadAll() 
orderby c.Name 
select new ComboBoxOptionGroup 
    { 
    Text = c.Name, 
    Options = from p in c.Projects 
       orderby p.Name 
       select new ComboBoxOption 
       { 
        Text = p.Name, 
        Value = p.ID.ToString() 
       } 
    } 

Leider führt diese LINQ Abfrage in num (Clients) +1 SQL-Abfragen. Gibt es eine elegante Möglichkeit, dies neu zu schreiben, so dass es nur zu einer SQL-Abfrage führt?

Meine Idee wäre, alle von Kunden bestellten Projekte zu holen und den Rest der Arbeit in zwei verschachtelten foreach-Schleifen zu erledigen, aber das scheint der Eleganz zu trotzen, die beabsichtigt war, als LINQ entworfen wurde. Gibt es bessere Möglichkeiten?

Antwort

2

Wenn ClientsRepository.LoadAll() ist ein Wrapper um eine Abfrage, die tatsächlich in die Datenbank geht und ruft die Daten (nicht IQueryable<T> nicht zurück), dann Sie stecken bleiben. Wenn es einen Teil einer Abfrage zurückgibt (gibt IQueryable<T> zurück), dann sollte es möglich sein.

Aber ohne zu wissen, wo die Daten (oder Objekt) Kontext ist und Ihr Modell ist es schwer.

Normalerweise würde ich erwarten, wie etwas zu tun:

from client in dataContext.Clients 
join p in dataContext.Projects on p.ClientId equals c.Id 
    into projects 
orderby client.Name 
select new ComboBoxOptionGroup { 
    Text = client.Name, 
    Option = from p in projects 
      orderby p.Name 
      select new ComboBoxOption { 
      Text = p.Name, 
      Value = p.ID.ToString() 
      } 
} 
1

Sie propably für „join“ Betreiber suchen: http://www.hookedonlinq.com/JoinOperator.ashx

+0

Danke für den Hinweis. Mir war eigentlich der Join-Operator bekannt, aber ich wusste nicht, dass es in diesem Fall zutrifft. Ich dachte nicht, dass Join tatsächlich zu GroupJoin führt. –

2

Eine weitere mögliche Alternative wäre DataLoadOptions zu verwenden.

DataLoadOptions dlo = new DataLoadOptions(); 
dlo.LoadWith<Client>(c => c.Projects); 
context.DeferredLoadingEnabled = false; // You may not need/want this line 
context.LoadOptions = dlo; 

Ich habe nicht diese Art und Weise zu tun, es getestet, aber Sie werden hoffentlich in der Lage sein, Ihre Abfrage in Ruhe zu lassen und die Anzahl der notwendigen Abfragen reduzieren.

+0

Interessant! Ich habe noch nie davon gehört. –

+0

Lassen Sie mich wissen, ob das für Sie funktioniert - Wie gesagt, ich habe es nicht getestet, also bin ich gespannt, wie es funktioniert. –

Verwandte Themen