Question

I've been trying to implement the IN clause in linq to sql. The SQL statement is:

SELECT KitId,PartId
FROM Kits k 
WHERE  k.PartId IN( 
    SELECT Id 
    FROM Parts p 
    WHERE CustomerId > 1 AND CustomerId < 100

I have read a number of SO entries on this, and have so far:

var subquery = (from p in Parts where p.Id > 1 && p.Id < 100 select new {p.ID}).ToArray();

var query = (from k in Kits
            where subquery.Contains(k.PartId)           
            select k).ToList();

There are compiler errors in the second statement: Delegate 'System.Func' does not take 1 arguments Cannot convert lambda expression to type 'string' because it is not a delegate type 'AnonymousType#1[]' does not contain a definition for 'Contains' and the best extension method overload 'System.Linq.Queryable.Contains(System.Linq.IQueryable, TSource)' has some invalid arguments Instance argument: cannot convert from 'AnonymousType#1[]' to 'System.Linq.IQueryable'

Substituting into the second statement the array: int[] subquery = {1,2,3};

Results in success. How would I manipulate the first array to arrive at a simple integer array?

EDIT: Altering the first statement to the below statement executes the second:

var subquery = from p in ctx.Parts
                            where p.CustomerId > 1 && p.CustomerId < 10
                            select p.Id
Was it helpful?

Solution

Define your subquery like this:

var subquery = (from p in Parts where p.Id > 1 && p.Id < 100 select p.ID).ToArray();

You want the actual ID, not an anonymous type with the single value of ID.

You shouldn't need the ToArray() part either, and the query should be faster if you define it as

var subquery = from p in Parts where p.Id > 1 && p.Id < 100 select p.ID

so that only one DB call is made instead of two.

OTHER TIPS

You can do that in one statement like:

var query = Kits.Where(k=> Parts
                            .Where(p=> p.Id > 1 && p.Id <100)
                            .Select(r=> r.Id))
                   .Contains(k.PartId);

You are getting the error because you are selecting anonymous type with select new {p.ID}, you can remove the error by not selecting an anonymous type instead do select p.ID. Also no need for ToArray call, let lazy evaluation of LINQ do the work for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top