开发者

Linq-to-Entities match ID in list of integers in a compiled query

开发者 https://www.devze.com 2023-03-06 15:06 出处:网络
I\'m trying to find a way to 开发者_如何学JAVAimplement a Linq-to-Entities compiled query of the form:

I'm trying to find a way to 开发者_如何学JAVAimplement 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?


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


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.


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.

0

精彩评论

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