Внедрение подобного оператора несколько раз в одном запросе Linq to Entities

У нас есть список строк, и нам нужно отфильтровать наши результаты по этому списку. Примером может быть поиск всех учащихся, чьи SSN начинаются с 465, 496 или 497 (плюс еще x)

List<string> list = GetPossibleStartsWithValues();
var qry = from student in entities.Students.WhereStartsWith(x=>x.SSN, list)
select new SearchedStudent
{
    Name = student.Name,
    SSN = student.SSN,
    ...
}

Код предоставлен здесь близок к тому, что нам нужно, но мы не можем понять, как реализовать нужный StartsWith с помощью класса Expression.


person johnnywhoop    schedule 07.09.2010    source источник


Ответы (2)


Что ж, вы можете попробовать это:

public static IQueryable<T> WhereStartsWith<T>(this IQueryable<T> source,
    Expression<Func<T, string>> projection,
    List<T> list)
{
    return source.Where(x => list.Any(y => projection(x).StartsWith(y)));
}

Это вполне может не сработать, но стоит попробовать, прежде чем переходить к чему-то более сложному.

РЕДАКТИРОВАТЬ: Как вы сказали, приведенное выше не будет компилироваться - вам в основном нужно построить дерево выражений, представляющее бит в предложении Where. Упс. Однако, прежде чем вы начнете это делать, стоит посмотреть, сработает ли это в конце концов. Попробуй это:

List<string> list = GetPossibleStartsWithValues();
var qry = from student in entities.Students
     .Where(student => list.Any(y => student.SSN.StartsWith(y)))
select new SearchedStudent
{
    Name = student.Name,
    SSN = student.SSN,
    ...
}

Если это не сработает, то делать более общий метод бесполезно :(

person Jon Skeet    schedule 07.09.2010
comment
Я не могу заставить код компилироваться. Я получаю сообщение об ошибке "проекция" является "переменной", но используется как "метод". Что мне нужно изменить? - person johnnywhoop; 07.09.2010
comment
@johnnywhoop: Упс. Исправлю, когда вернусь домой. - person Jon Skeet; 07.09.2010
comment
Да, это сработало. Ускорит ли создание выражения? Это кажется довольно медленным, но его можно использовать. - person johnnywhoop; 10.09.2010
comment
@johnnywhoop: взгляните на сгенерированный SQL. Кажется довольно медленным, не очень точным... не глядя на SQL, вы не можете сказать, что происходит. - person Jon Skeet; 10.09.2010

Как насчет использования составного оператора, такого как

var qry = from student in entities.Students.Where( 
             s => list.Where( x => s.StartsWith(x)).Count() != 0 )
person Rod    schedule 07.09.2010