2016-02-10 9 views
5

Ich habe 3 Tabellen in meiner Datenbank.Entity Framework Join Abfrage mit int Array

--- --- Studenten

id - Name

--- Sprache auswählen ---

id - lang

- -StudentLanguage --- (Gemeinsame Tabelle)

id - StudentID - LANGID

Schüler können mehr Sprachen haben. Ich möchte Studenten mit einem int[] Array-Werte suchen. Aber nicht mit IN() - Contains(), es muss mit and - && Betreiber und dieser Betreiber int[] Werte sein.

in sql =

`select t1.id, t1.name from Student t1 join StudentLanguage t2 
ON(t1.id=t2.studentId) where (t2.langId=1 and t2.langId=3 and t2.langId=5);` 

so wie kann ich diese Abfrage mit Entity Framework zu tun? (... where new int[] { 1,3,5 })

+0

Alles, was mir einfällt, ist das Durchlaufen Ihres Arrays und das Ausführen einer separaten Abfrage innerhalb jeder Schleifeniteration. Dann können Sie die Ergebnisse zusammen in eine Ergebnismenge – rory

+0

@rory verschmelzen, aber OP möchte Lösung in linqToSQL ich gess –

+0

@teovankot Antwort mit Pseudo-Code gegeben – rory

Antwort

1

Versuchen Sie so etwas wie dieses ...

resultArr = []; 

For(int i = 0; i<arr.length; i++) { 
    var result = db.Student.Where(s=>s.StudentLanguage.langId == arr[i]); 
    resultArr.append(result); 
} 
+0

Bist du sicher, dass du es in C# geschrieben hast? –

+0

@teovankot - Pseudo C#. Wir spoonfeed nicht um diese Teile hier ;-) – rory

+0

@rory danke, aber wo ist Join-Anweisung in Ihrem Entity-Framework linq Abfrage? Dafür gibt es eine gemeinsame Tabelle. – ASPMaker

3

Dieser Code generieren einige ungeschickte SQL-Abfrage ...

 int[] ids = new[] { 1, 3, 5 }; 
     var acc = from st in db.Students select st; 

     foreach (var id in ids) 
     { 
      int id1 = id; 
      var res = 
       from st in db.Students 
       from lng in st.Language 
       where lng.Id == id1 
       select st; 
      acc = 
       from a in acc 
       join st in res on a.Id equals st.Id 
       select a; 
     } 

     acc.ToList(); 

... SQL-Abfrage:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name] 
FROM [dbo].[Student] AS [Extent1] 
INNER JOIN [dbo].[StudentLanguage] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Student_Id] 
INNER JOIN [dbo].[StudentLanguage] AS [Extent3] ON [Extent1].[Id] = [Extent3].[Student_Id] 
INNER JOIN [dbo].[StudentLanguage] AS [Extent4] ON [Extent1].[Id] = [Extent4].[Student_Id] 
WHERE ([Extent2].[Language_Id] = @p__linq__0) 
     AND ([Extent3].[Language_Id] = @p__linq__1) 
     AND ([Extent4].[Language_Id] = @p__linq__2) 
+0

Warum Sie wenig ... –

0

Ich versuche zu suchen, wie es geht, und hier ist, was ich herauskommen:

int[] langIds = new int[] { 1, 3, 5 }; 
var lang = _context.Languages.Where(x => langIds.Contains(x.id)); 
var result = _context.Students.Where(x => !lang 
            .Except(x.StudentLanguages 
             .Select(y => y.Language) 
            .Intersect(lang)).Any()); 

Hier verwende ich Except und IntersectLinqToSql Erweiterungsmethoden.

Es produziert diese SQL-Anweisung:

SELECT [t0].[id], [t0].[name] 
FROM [dbo].[Student] AS [t0] 
WHERE NOT (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM (
     SELECT DISTINCT [t1].[id], [t1].[name] 
     FROM [dbo].[Language] AS [t1] 
     WHERE (NOT (EXISTS(
      SELECT NULL AS [EMPTY] 
      FROM (
       SELECT DISTINCT [t3].[id], [t3].[name] 
       FROM [dbo].[StudentLanguage] AS [t2] 
       INNER JOIN [dbo].[Language] AS [t3] ON [t3].[id] = [t2].[langId] 
       WHERE (EXISTS(
        SELECT NULL AS [EMPTY] 
        FROM [dbo].[Language] AS [t4] 
        WHERE ([t3].[id] = [t4].[id]) AND ([t4].[id] IN (@p0, @p1, @p2)) 
        )) AND ([t2].[studentId] = [t0].[id]) 
       ) AS [t5] 
      WHERE [t1].[id] = [t5].[id] 
      ))) AND ([t1].[id] IN (@p3, @p4, @p5)) 
     ) AS [t6] 
)) 

Bitte beachte, dass ich Sprachen aus der Datenbank zu füllen. Leider Sie können nicht lokale Sammlungen in Ihrer Abfrage verwenden, da LinqToSQL nicht wissen, wie man sie in SQL übersetzt.Wenn Sie die gleiche Sache mit lokalen int-Array oder einer anderen Sammlung tun, werden Sie diese Ausnahme erhalten:

LINQ to SQL-Ausnahme: Lokale Sequenz kann nicht in LINQ verwendet werden Implementierung von Abfrageoperatoren in SQL außer der Betreiber Enthält

3
List<int> langIds = new int[] { 1, 3, 5 }.ToList(); 
var c = langIds.Count; 
var res2 = _context.Students 
    .Where(x => x.StudentLanguages 
     .Where(l => langIds.Contains(l.langId)).Select(y => y.langId).Distinct().Count() >= c); 

Ergebnis SQL:

SELECT [t0].[id], [t0].[name] 
FROM [dbo].[Student] AS [t0] 
WHERE ((
    SELECT COUNT(*) 
    FROM (
     SELECT DISTINCT [t1].[langId] 
     FROM [dbo].[StudentLanguage] AS [t1] 
     WHERE ([t1].[langId] IN (1, 3, 5)) AND ([t1].[studentId] = [t0].[id]) 
     ) AS [t2] 
    )) >= 3 

Verwenden Distinct wenn StudentLanguages theo retikal kann mehrere überlappende Bündel haben StudentId - LangId.

0
var db = new MyDbContext(); 
var langIds = new[] { 1, 3, 5 }; 

IEnumerable<Student> student = from st in db.student select st; 

foreach (var item in langIds) 
{ 
    student = student.Join(db.StudentLanguage.Where(w => w.langId == item), 
    st => st.studentId, 
    stMap => stMap.id, 
    (st, stMap) => new { Student= stMap, StudentLanguage = st}) 
    .Select(x => x.Student).Distinct(); 
} 

ich kann das so machen. Vielleicht foreach kann LINQ sein und dieser Code kann nur eine Zeile und ein wenig kurz sein.

+0

Ihre Abfrage hat einen Fehler in der letzten Zeichenfolge. Sie wählen Anonymouse-Typ. –

+0

@teo van kot aber es gibt wahres Ergebnis für mich zurück. – ASPMaker

Verwandte Themen