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;
}
Надеюсь, вы получили мои слова.