2012-03-28 4 views
0

Ich habe eine SQL-Abfrage (unten), die im Wesentlichen einen Schüler von tbStudents nimmt, und dann den letzten Begriff (eine Zahl, aber als String gespeichert) in tbTerms.SQL -> LINQ (C#)

Es gibt eine Eins-zu-viele-Beziehung mit einem Studenten in tbStudents zu einem Termbank in tbTerms. Beispiel:

tbStudents:

StudentId FirstName LastName 
12345  John  Smith 
12346  Jane  Doe 

tbTerms:

StudentId Term 
12345  1234 
12345  1235 
12345  1236 
12346  1233 
12346  1234 

Gewünschter:

StudentId FirstName LastName Term 
12345  John  Smith 1236 
12346  Jane  Doe  1234 

SQL-Abfrage:

select tbStudents.student_id, tbStudents.user_id, tbStudents.firstname, tbStudents.lastname, v.rTerm 
    from tbStudents 
    inner join (
     select tbTerms.student_id, MAX(tbTerms.term) as rTerm 
     from tbTerms 
     group by tbTerms.student_id 
    ) v on v.student_id = tbStudents.student_id 

Ich habe versucht, dies alles in eine LINQ-Anweisung zu bringen, aber ich habe Probleme. Gibt es das überhaupt in einer Aussage? Oder muss es in mehreren Aussagen gemacht werden. Danke im Voraus.

Bearbeiten: C# -Code von dem, was ich versucht habe.

var students = (from s in dockDb.tbStudents 
       join t in dockDb.tbTerms on s.student_id equals t.student_id 
       into pairs 
       from p in pairs 
       select new { UserId = s.user_id, StudentId = s.student_id, Term = p.term }).ToList(); 

Ausgang ist ähnlich:

StudentId FirstName LastName Term 
12345  John  Smith 1234 
12345  John  Smith 1235 
12345  John  Smith 1236 
12346  Jane  Doe  1233 
12346  Jane  Doe  1234 

Edit # 2: Ich bin für die Daten Entity Framework. Ich bin mir nicht sicher, ob das irgendwas betrifft, aber die meisten Lösungen sind 'syntaktisch falsch', wenn ich sie versuche.

+2

Können Sie zeigen, was Sie bereits haben? –

+0

"syntaktisch falsch". Rufen Sie die Erweiterung AsEnumerable() auf. Dann werden sie nicht "syntaktisch inkorrekt" sein. – OmegaMan

Antwort

0

Sollte möglich sein. Versuchen Sie dies:

from s in Students 
join t in Terms on t.StudentId = s.StudentId 
select new {Student = s, Term = t} 
group by s into g 
select new {g.Key.StudentId, g.Key.FirstName, g.Key.LastName, g.Max(x=>x.Term.term)}; 

Breaking down, die ersten beiden Zeilen definieren die Domäne, in der gesucht werden soll; nämlich die intern verbundene Kombination von Studenten und Termen, die durch StudentId verknüpft sind. Jede eindeutige Kombination aus Student und Term wird in einen anonymen Typ gestellt, und dann werden diese Instanzen nach jedem eindeutigen Student in einem Lookup gruppiert (eine schreibgeschützte Sammlung von IEnumerables, auf die der Schlüssel verweist). Wir können die wichtigen Informationen des Schlüssels (Studenten) auswählen und in der Liste der Begriffe den mit dem höchsten Wert finden (der der letzte ist).

+0

Ich musste einige Dinge in Ihrem Code ändern, um es laufen zu lassen, aber ansonsten war Ihre Struktur ziemlich genau das, was ich brauchte. Vielen Dank! – Mike

1

Sie sollten so etwas versuchen:

from s in dockDb.tbStudents 
join t in dockDb.tbTerms on t.student_id equals s.student_id into st 
group st by New {StudentID = st.student_id, Term = t.term} into g 
select New { g.Key, g.Max(i => i.Term) } 
0

Irgendwie, ich habe zu schreiben, immer als Syntax mit Erweiterungsmethoden besser lesbar und natürlich zu sein. Also, hier geht:

context.Students.Select(s => new 
{ 
    s.StudentId, 
    s.FirstName, 
    s.LastName, 
    Term = context.Terms.Where(t => t.StudentId == s.StudentId) 
         .Select(t => t.TermNumber) 
         .OrderByDescending(t => t) 
         .First() 
}); 

Grundsätzlich für jeden Schüler, sie alle seine/ihre Begriffe auswählt, ordnet sie aus jüngsten bis zur ältesten und enthält erste (die jüngsten) in Folge.

0

Groupby ist dein Freund. Lassen Sie uns einfach die Daten nach Studenten ID gruppieren, dann Projekt es in ein neues Formular.Dies ist ein LINQPad Beispiel:

void Main() 
{ 
    var students = new List<Student>() 
    { 
     new Student() { StudentID = 12345, Name = "Smith" }, 
     new Student() { StudentID = 12346, Name = "Jones" } 
     }; 

    var terms = new List<Term>() 
    { 
     new Term() { StudentID=12345, TermID = 1234 }, 
     new Term() { StudentID=12345, TermID = 1235 }, 
     new Term() { StudentID=12345, TermID = 1236 }, 
     new Term() { StudentID=12345, TermID = 1237 }, 
     new Term() { StudentID=12346, TermID = 1233 }, 
     new Term() { StudentID=12346, TermID = 1234 }, 
    }; 

    var result = terms.GroupBy (tm => tm.StudentID) 
         .Select (gr => new 
    { 
     Name = students.First (s => s.StudentID == gr.Key).Name, 
     Terms = gr.Select (g => g.TermID) 
    }); 


    result.Dump(); 

} 

// Define other methods and classes here 
    public class Student 
    { 
     public int StudentID { get; set; } 
     public string Name { get; set; } 
    } 

    public class Term 
    { 
     public int StudentID { get; set; } 
     public int TermID { get; set; } 
    } 

Hier ist die Ausgabe, die verwendet werden können:

enter image description here