开发者

Good practice for using "NOT IN" in a LINQ query

I have converted the following SQL query to LINQ with the exception o开发者_如何学Gof the "NOT IN" subquery.

What would be the most effective way to implement this using LINQ? Should I use a join instead?

If anybody is able to provide an example or some guidance, I'd appreciate it.

New LINQ Query:

     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
               };

Old SQL Query:

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


There are a couple of ways of doing the not in. Below is just a quick sample put in LinqPad as a test.

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

}

I normally play with code first in LinqPad as it helps me understand any problems, and it will (if you're working with SQL) then show you what SQL the query will generate and you can fine tune a little. Sometimes it takes a little time to get your stuff able to be run in there, but it's worth it with the more complex queries.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜