LINQ: когда использовать скомпилированные запросы?

Я бы хотел получить совет по этому поводу. Я использовал скомпилированные запросы раньше, но для этого конкретного случая я не уверен, подходит ли это.

Это форма поиска, в которой запрос изменяется и зависит от того, на что выполняется поиск.

static Func<DBContext, int, IQueryable<Foo>> Search = CompiledQuery.Compile(
    (DBContext db, int ID) =>
        db.Person
            .Where(w => w.LocationID = ID)
            .Select(s => 
                new Foo 
                { 
                    Name = s.PersonName, 
                    Age = s.Age,
                    Location = s.LocationName,
                    Kin = s.Kin
                }));

Теперь, если кто-то заполняет окно поиска, я хочу расширить запрос, добавив в запрос еще один оператор Where:

var query = Search(context, 123);
query = query.Where(w => w.Name.Contains(searchString));

Итак, мой вопрос заключается в том, что он возвращает все результаты, где LocationID == 123, а затем проверяет результаты для соответствия searchString? Или это фактически расширяет скомпилированный запрос?

Если это первый (я подозреваю, что это так), следует отказаться от CompiledQuery и просто создать метод, который расширяет запрос, а затем возвращает его как список?

Кроме того, каковы наилучшие методы использования CompiledQuery и есть ли руководство по их использованию?

Примечание. Я использую приведенное выше на веб-сайте ASP.NET с Linq to SQL. Не уверен, что это имеет значение.

Спасибо

Ответ 1

Проблема заключается в том, что скомпилированный запрос задан в камне; он знает, какой SQL он будет работать против базы данных. Однако выражение лямбда имеет ленивую загрузку и не может изменять запрос компиляции во время его запуска во время выполнения. Плохая новость заключается в том, что он вернет все записи из базы данных, но будет запрашивать эти записи в памяти для дальнейшего уточнения их.

Если вы хотите скомпилировать запрос, я бы предложил написать два запроса с разными сигнатурами.

Ответ 2

Насколько я знаю, целесообразно скомпилировать ваш запрос один раз, то есть весь смысл предварительно скомпилированного запроса (и почему ваш предварительно скомпилированный запрос является статическим), это экономит время, чтобы скомпилировать этот запрос в SQL. Если он расширяет этот предварительно скомпилированный запрос, то он снова компилирует этот запрос, который вы теряете.

Результат запроса по результату (ваша переменная запроса) больше не является LINQ to SQL.

Ответ 3

Просто добавьте дополнительное условие в свой скомпилированный запрос.

DB.Person.Where(w => w.LocationID == ID 
                     & (searchString=="" || w.Name.Contains(searchString)))

Ответ 4

Если я прав, вам нужно какое-то динамическое предложение where в linq. Поэтому для этого я бы предложил пойти таким образом

IEnumerable list;

if(condition1)
{
  list = Linq Statement;
}

if(condition2)
{
  list = from f in list where con1=con && con2=con select f;
}

if(condition3)
{
 list = from n in list  con1=con && con2=con select f;
}

Надеюсь, вы получили мои слова.