LINQ: Когда использовать скомпилированные запросы? - PullRequest
10 голосов
/ 22 сентября 2011

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

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

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 . Не уверен, что это имеет какое-то значение.

Спасибо

Ответы [ 4 ]

2 голосов
/ 22 сентября 2011

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

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

0 голосов
/ 22 сентября 2011

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

DB.Person.Where(w => w.LocationID == ID 
                     & (searchString=="" || w.Name.Contains(searchString)))
0 голосов
/ 22 сентября 2011

Если я прав, то вам нужно некоторое динамическое предложение 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;
}

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

0 голосов
/ 22 сентября 2011

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

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

...