2016-07-11 4 views
3

Let JOIN sagen, ich habe:Kettenselect anstelle der Verwendung einer Anweisung

enter image description here

Ich habe alle Klassen finden, die zu einer bestimmten Schule gehören (IdSchool = 2) und die von der Wissenschaft zum Beispiel ist .

Anyways, weil ich finde LINQ sehr EASSy zu verwenden, ich mache:

using(var context = new MyEntities()) 
{ 
    var classesOfInterest = context.Schools 
         .SelectMany(x => x.Teachers) 
         .SelectMany(x => x.Classes) 
         .Where(x => /* custom criteria */) 
         .ToList(); 
} 

Also meine Frage ist: Ist mit diesem Ansatz instad der Verwendung einer Anweisung schlechte Praxis kommen? Soll ich stattdessen eine JOIN-Anweisung verwenden? Es gibt Fälle, in denen ich 5 "SelectMany" -Anweisungen ketten. Im Moment funktioniert es gut, weil die Datenbank klein ist. Wenn ich mit einer großen Datenbank arbeiten soll, sollte ich das vermeiden?

+2

Ich würde erwarten, dass die Ausführung der übersetzten SQL-Abfrage mit der 'SelectMany'-Methode viel langsamer ist. Ich würde definitiv Joins verwenden. Aber nimm mein Wort nicht dafür. Protokollieren Sie das generierte SQL, vergleichen Sie die Ausführungspläne und sehen Sie selbst. – sstan

+0

Danke @Sstan. Die Ergebnisse sind sehr ähnlich. Ich denke, ich muss dies erneut versuchen, eine große Datenbank und vergleichen Sie die Ergebnisse wie Sie sagen. Es wäre schön, wenn ich es mit SelectMany verketten könnte. Es ist so schneller, die Abfragen so zu erstellen. –

+2

Eigentlich ist dies der bevorzugte EF-Ansatz. EF verwendet die Metainformationen der "navigation" -Eigenschaften, um die Joins für Sie zu generieren. –

Antwort

3

Wird dieser Ansatz verwendet, um eine fehlerhafte Join-Anweisung zu verwenden?

Überhaupt nicht. In der Tat ist dies die empfohlene (oder bevorzugte) Praxis bei der Arbeit mit EF. Die so genannten Navigationseigenschaften sind eine der Schönheiten der EF. Wenn Sie sie haben (und Sie tun), müssen Sie niemals "manuelle" Joins verwenden. Sie "navigieren" einfach, wenn sie Objekte/Sammlungen sind, und EF erzeugt die Joins für Sie, wenn Sie wie sie geschrieben haben, aber ohne sich merken zu müssen, welches Feld von der einen Tabelle zu welchem ​​Feld der anderen Tabelle gehört.

Zum Beispiel lassen Sie diese vereinfachte Version der Abfrage nehmen:

var queryA = context.Schools.SelectMany(x => x.Teachers); 
var sqlA = queryA.ToString(); 

und das Äquivalent Joins:

var queryB = from s in context.Schools 
      join t in context.Teachers on s.Id equals t.IdSchoool 
      select t; 
var sqlB = queryB.ToString(); 

Sie werden sehen, dass sqlA und sqlB sind ein und dasselbe.

+0

Sind Sie sicher, dass 'SelectMany' von' IQueryable 'in einen inneren Join übersetzt wird? – octavioccl

+0

@octavioccl Absolut. Was sonst? 'SelectMany' steht zB, wenn du' s aus d in .Schulen aus t in an Lehrer wählst t '. Und es heißt übersetzt "INNER JOIN". Wenn Sie 's.Teachers.DefaultIfEmpty()' verwenden, erhalten Sie 'LEFT OUTER JOIN'. –

+0

Nun, ich dachte, es könnte auch eine Kreuzung sein mit einer Bedingung. Soweit ich weiß, wird ein doppeltes 'von' in Linq in einen 'SelectMany'-Aufruf übersetzt, deshalb dachte ich, es könnte in einen Cross-Join übersetzt werden. – octavioccl

Verwandte Themen