Question

I'm trying to find a way to implement a Linq-to-Entities compiled query of the form:

Func<MyEntities, List<int>, IQueryable<MyClass>> query = System.Data.Objects.CompiledQuery.Compile(
    (MyEntities entities, List<int> IDs) => (
         (from au in entities.Mine where IDs.Any(x => x == au.ID) select au)
    ));

Because only scalar parameters can be passed to CompiledQuery.Compile the above fails. I'm trying to find some clever way to pass a comma delimited list of integers as a string and use that in the L2E query along the lines of:

Func<MyEntities, string, IQueryable<MyClass>> query = System.Data.Objects.CompiledQuery.Compile(
    (MyEntities entities, string IDs) => (
         (from au in entities.Mine where IDs.Split(',').Any(x => Convert.ToInt32(x) == au.ID) select au)
    ));

But that doesn't work due to the unsupported Split function.

Any clever ideas about how this could be implemented?

Was it helpful?

Solution 2

I ended up finding a way to do it but it's way too slow at around 3s.

string ids = "|" + String.Join("|", new List<int> { 4, 5, 6, 7, 8, 9, 10, 20, 23, 34 }) + "|";   

Func<MyEntities, string, IQueryable<MyClass>> query =     System.Data.Objects.CompiledQuery.Compile(
(MyEntities entities, string IDs) => (
     (from au in entities.Mine where IDs.Contains("|" + SqlFunctions.StringConvert((decimal)au.ID).Trim() + "|")select au)
)); 

Back to the drawing board.

OTHER TIPS

I'm not sure if this could possibly work, but maybe try to use join of List<int> IDs and MyEntities entities?

You can't.

What does CompiledQuery do? It pre-converts the query to a canonical command tree -- an intermediate representation used to generate SQL by the provider.

The SQL for a command with a scalar param is the same structure regardless of the param value. But the SQL generated for, say, a list of 2 items will be structurally different from the SQL afor a list of 3 items, because it takes one fewer OR predicate in its WHERE clause. Most DB servers won't take lists as a param value, after all.

Your string/| kludge works because you're now passing only one param, not a list, to the DB server. But as you've seen, the server can't index such a query, so it will be slow.

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