在LINQ查询中使用“NOT IN”的良好实践

时间:2011-08-17 10:40:47

标签: asp.net-mvc-3

我已将以下SQL查询转换为LINQ,但“NOT IN”子查询除外。

使用LINQ实现此目的的最有效方法是什么?我应该使用连接吗?

如果有人能提供示例或指导,我会很感激。

新的LINQ查询:

     return from objOpenCalls in db.OpenItemss
               from objTasks in db.Tasks
                .Where(t => (t.Task_ID == objOpenCalls.Parent_Task_ID))
                where ((objTasks.Item_ID > 0) && (objTasks.Type_ID > 0) && (objTasks.OwnerTypeItem_ID == user)  && (objOpenCalls.CallEnd < DateTime.Now))
                orderby objOpenCalls.CallStart descending
               select new CallMiniViewModel
               {
                   ID = objOpenCalls.ID,
                   CallStart = objOpenCalls.CallStart,
                   Name = objTasks.Task_Title
               };

旧SQL查询:

SELECT  TOP (100) ta.ID, t.Task_Title, ta.CallStart
FROM         OpenItems AS ta INNER JOIN
                      Tasks AS t ON ta.Parent_Task_ID = t.Task_ID
WHERE   
(t.Item_ID > 0) AND (t.[Type_ID] > 0) AND (ta.CallStart > DATEADD(m, -6, GETDATE())) 
AND (ta.ID NOT IN (SELECT     CallId FROM CallFeedback)) AND (t.OwnerTypeItem_ID = @Username)     AND (ta.CallEnd < GETDATE())
ORDER BY ta.CallStart DESC

1 个答案:

答案 0 :(得分:2)

有几种方法可以不用。以下只是LinqPad中的一个快速示例作为测试。

class MyClass {
    public int Id {get;set;}
}

void Main()
{
    int[] myItems = new[] { 1, 2, 3, 4, 5, 6 };

    IEnumerable<MyClass> classes = new []{ 
        new MyClass { Id = 3 },
        new MyClass { Id = 6 },
        new MyClass { Id = 8 }
    };

    var results = from cl in classes
                    where !myItems.Contains( cl.Id ) 
                    select cl;                                  

    foreach(var result in results) {
        Console.WriteLine( "Class {0}", result.Id);
    }

    var results2 = from cl in classes
                    where ( 
                        from i in myItems
                        where i == cl.Id
                        select i ).Count( ) == 0 
                    select cl;

    foreach(var result in results2) {
        Console.WriteLine( "Class {0}", result.Id);
    }               

}

我通常在LinqPad中首先使用代码,因为它可以帮助我理解任何问题,并且它会(如果您正在使用SQL)然后向您展示查询将生成什么SQL,并且您可以微调小。有时需要花一点时间让你的东西能够在那里运行,但是对于更复杂的查询来说它是值得的。