views:

39

answers:

1

I'm attempting to write a CompiledQuery using Linq-to-Entities that will replace a stored procedure that takes two array (in this case, comma-delimited TEXT) parameters. Essentially, the SQL is be something like this:

*Stored Proc definition*
@ArrayParm1    TEXT,
@ArrayParm2    TEXT
-- etc. 
SELECT [fieldList] 
FROM someTable
WHERE someTable.Field1 IN (SELECT * FROM dbo.fncCSVToTable(@ArrayParm1))
AND someTable.Field2 IN (SELECT * FROM dbo.fncCSVToTable(@ArrayParm2))

dbo.fncCSVToTable creates a single-column temp table with the array values.

Converting this to a compiled Linq-to-Entities query didn't seem difficult:

public static Func<EntityContext, List<int>, List<string> IQueryable<EntityType>>
    SomeQuery = 
        CompiledQuery.Compile((EntityContext context, List<int> arrayParm1, 
                               List<string> arrayParm2) =>
            from c in context.SomeTableEntities
            where arrayParm1.Contains(c.Field1)
                && arrayParm2.Contains(c.Field2)
            select new EntityType
            { 
                //projection
            });

However, I get a runtime error stating that the parameters of Func<> cannot be a List, and that only scalar parameters are supported. This makes sense to me, but I still feel like there's got to be a way to do this in a compiled query. Does anyone know of any way to do List.Contains or WHERE ... IN type functionality in a L2E CompiledQuery?

+2  A: 

I suspect that in the generated SQL for the non-compiled query, it's using

WHERE someTable.Field1 In (?, ?, ?)

for three values, for example... rather than the fncCSVToTable function.

Now part of the point of compiling the query is to work out the SQL in advance... and here, the exact SQL will depend on the number of items in the lists (because it will need that many query parameters). I suspect that makes it sufficiently awkward that it's just not supported.

Jon Skeet
+1; this is right. As for workarounds, write a new provider which caches queries based on list param counts or use a DB table instead of a list. Both are a bit involved.
Craig Stuntz
OK, this makes sense. So in this case I am not going to be able to use a CompiledQuery. Thanks!
AJ