2017-05-10 4 views
0

Ich habe Probleme beim Einrichten einer LINQ-Abfrage, die mehrere (4) Tabellen aus meiner Datenbank verwendet. Ich bin in der Lage, zwei Tabellen ohne ein Problem mit der LINQ-Syntax, die ich lerne, zu verbinden, aber mehr als das gibt mir Ärger. Ich versuche, die folgende SQL-Abfrage in LINQ-Format zu konvertieren.LINQ mit mehreren .join-Erweiterungen mit mehreren (4) oder mehr Tabellen

select count(distinct applicant) 
from apps inner join 
    stu_terms on applicant = student_id inner join 
    acad_prog on apps_program = acad_program and st_acad_lvl = acad_lvl inner join 
    application_statuses on apps_status = application_status 
where st_active_cred >= 0 and apps_start_term = @term and 
     apps_admit_status = @status and apps_stu_type = @type and 
     application_code is not null 

Ich bin neu in LINQ-Abfragen und wie alles zusammen passt, aber das ist, was ich kam mit. Es ist ein wenig schwierig, weil zusammen mit 4 Tabellen die where-Klausel aus drei der verschiedenen Tabellen zieht und die Art, wie ich sie einstelle, zwingt mich, die .Where() -Methode in meine Abfrage zu streuen. Siehe unten:

int num = db.apps.Distinct() 
      .Join(db.application_statuses, 
      a => a.apps_status, 
      aa => aa.application_status, 
      (a, aa) => new { apps = a, application_statuses = aa }) 
      .Where(j => j.apps.admit_status == status && j.apps.apps_stu_type == type && j.apps.apps_start_term == term && j.application_statuses.application_code != null) 
       .Join(db.stu_terms, 
       a => a.apps.applicant, 
       st => st.student_id, 
       (a, st) => new { apps = a, stu_terms = st }) 
       .Where(j => j.stu_terms.st_active_cred >= 0) 
        .Join(db.acad_prog, 
        a => a.apps.apps.apps_program, 
        ap => ap.acad_program, 
        (a, ap) => new { apps = a, acad_prog = ap }) 
         .Join(db.stu_terms, 
         ap => ap.acad_prog.acad_lvl, 
         st => st.st_acad_lvl, 
         (ap, st) => new { acad_prog = ap, stu_terms = st }).Count(); 

Wie Sie sehen können, die Wo-Methode in zwei getrennten Orten ist, weil es nur in der Lage sein würde, die Spalten aus der spezifischen Tabelle an den Stellen zu sehen. Die Mehrheit der Probleme, die ich sehe, ist, weil ich mir nicht bewusst bin, ob ich diese vier Tische sogar richtig zusammenfüge. Das meiste ist noch neu für mich (die zufällige Platzierung der Distinct() Methode zeigt das)

Ich schätze die Hilfe.

+1

Wenn Ihre Abfrage so komplex ist, tun Sie es nicht mit linQ – raven

+0

Was ist das? Linq2SQL oder EntityFramework? Haben Sie Beziehungen zu Ihrem Modell? – fhogberg

+0

@fhogberg Dies ist Entity Framework. Und ich glaube es nicht. Diese Tabellen enthalten Spalten, die ähnliche Daten enthalten, aber keine FK (s) sind. – jcbrom

Antwort

0

LINQ hat bereits die Verbindungen in Ihrem Domain-Modell (nicht vergessen, ICollection, wenn Sie Code-First verwenden)

Sie also don‘ t müssen die Joins angeben. Standardmäßig wird Lazy geladen, dh die Joins werden automatisch erstellt, wenn Sie sie verwenden (= Call .ToList()).

Eg.

db.Apps.Where(el => el.Students.Any(dl => dl.Type == 'Something')).ToList() 

Wenn Sie etwas schnellere Leistung möchten, können Sie eifrig laden mit Include verwenden. Welche erstellt die Verknüpfungen von Anfang an.

db.Apps.Include(el => el.Students.Select(dl => dl.childOfStudents)) 

Da bist du neu. Sie sollten außerdem wissen, dass alle Ihre Abfragen nach Änderungen verfolgt werden, wodurch sich die Leistung verringert.

Wenn Sie Objekte nicht ändern und aktualisieren müssen, verwenden Sie .AsNonQueryable() für eine etwas bessere Leistung.

PS. Sie können immer noch SQL verwenden ->https://msdn.microsoft.com/en-us/library/jj592907(v=vs.113).aspx :)

+0

Die Art und Weise, wie ich mit der DB arbeite, ist Setup, ich denke, nur mit Raw SQL-Abfragen wird mir eine Menge Kopfschmerzen ersparen. Ich schätze die Hilfe. – jcbrom

0

Sie sehr verwenden selten Join() in LINQ mit Datenbanken. Stattdessen navigieren Sie einfach durch die Navigationseigenschaften. Mit einem geeigneten Modell ist dies so einfach wie:

 var q = from a in apps 
       where a.StuTerms.ActtiveCredits > 0 
       && a.StartTerm = startTerm 
       && a.ApplicationStatus.AdmitStatus = admitStatus 
       && a.StudentType = studentType 
       && a.application_code != null 
       select a; 

    var applicants = q.GroupBy(a => a.ApplicantId).Count(); 

David

+0

Wenn man den Kommentar von OP oben sieht, scheint dies einer dieser seltenen Fälle zu sein. Aber vielleicht könnten Sie als Alternative auch zeigen, dass die Abfragesyntax sowieso viel einfacher ist, auch bei Joins. Übrigens gibt es in Ihrer Anfrage kein 'select'. –

+0

"Dies scheint einer dieser seltenen Fälle" Ich glaube nicht. Sie benötigen keine echten FKs in der Datenbank, um Navigationseigenschaften und Fremdschlüsselspalten im EF-Modell zu deklarieren. –