实体框架使用int数组连接查询

时间:2016-02-10 10:26:31

标签: sql asp.net-mvc entity-framework

我的数据库上有3个表。

--- ---学生

id - name

--- ---语言

id - lang

--- StudentLanguage ---( Common Table

id - studentId - langId

学生可以使用更多语言。我想搜索具有int[]数组值的学生。但不是IN() - Contains(),而是and - &&运算符,此运算符采用int[]值。

在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);`

那么如何使用Entity Framework进行此查询? (... where new int[] { 1,3,5 }

5 个答案:

答案 0 :(得分:3)

此代码生成一些笨拙的SQL查询...

        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查询:

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)

答案 1 :(得分: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);

结果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

如果Distinct理论上可能包含多个重叠的约束StudentLanguages - StudentId,请使用LangId

答案 2 :(得分:1)

尝试这样的事情......

resultArr = [];

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

答案 3 :(得分:0)

我尝试搜索如何做到这一点,这就是我的结果:

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());

在这里,我使用ExceptIntersect linqToSQL 扩展方法。

它产生这个SQL语句:

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]
))

请注意,我从数据库填充语言。不幸的是您无法在查询中使用本地集合,因为LinqToSQL不知道如何将它们转换为SQL。如果你对本地int数组或任何其他集合做同样的事情,你将得到这个例外:

  

LINQ To SQL异常:本地序列不能在LINQ to SQL中使用   查询运算符的实现,包含Contains运算符

答案 4 :(得分:0)

fun main(args: Array<String>) {
    val s: String? = null

    val maybeSubstring = nullableSubstring(s, 0, 1)
    val alsoMaybeSubstring = s?.extensionSubstring(0, 1)
我可以这样做。也许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(); } 可以转为linq,这段代码只能是一行而且有点短。