LINQ (L2E) с хранимой процедурой и IQueryable

#c# #sql-server #linq-to-entities

#c# #sql-сервер #linq-to-entities (привязка к объектам)

Вопрос:

Рассмотрим обычное выражение Linq, которое будет примерно таким:
(Это всего лишь пример, чтобы сделать вещи более понятными)

  IQueryable<Person> personQuery= (from ppl in PersonContext  
                      select ppl).ASQueryable();


List<Person>personList = personQuery.where(x => x.age==13).ToList();
  

Итак, если бы я решил поместить 1-ю часть запроса linq внутри хранимой процедуры,

все получится примерно так.

  IQueryable<Person> personQuery= PersonContext.sp_RetrievePerson().ASQueryable();

 List<Person> personList = personQuery.where(x => x.age==13).ToList();
  

Итак, что касается вопроса, я полагаю, что 1-й метод отправляет sql-вызов только при вызове ToList().
Другими словами, запрос, отправленный в sql для выполнения, будет

 Select * from Person where age=13
  

Но для метода 2, сколько раз этот запрос будет отправлен на выполнение?
Если запрос отправляется только 1 раз, делает ли это избыточным вызов хранимой процедуры, поскольку хранимая процедура известна более быстрым выполнением, и как будет выглядеть запрос, отправленный в sql?

Ответ №1:

Я не уверен насчет этого, но PersonContext.sp_RetrievePerson() возвращает ObjectResult , который внутренне использует DbDataReader. Это означает, что хранимая процедура вызывается один раз, personQuery.where(x => x.age==13) выполняет итерацию по результирующим строкам и отфильтровывает не совпадающие объекты.

Используя хранимые процедуры для этого, вы можете получить небольшой прирост производительности при запросе базы данных, но вам придется оценивать каждый объект в таблице persons после считывания его из базы данных. Поэтому я думаю, что в этом сценарии использование хранимых процедур имеет смысл, только если вы предоставляете параметр age хранимой процедуре для фильтрации результатов, уже имеющихся в базе данных.

Комментарии:

1. Это то, о чем я тоже догадываюсь. Конечно, это более сложный запрос, чем этот пример. Я не очень силен в SQL, когда дело доходит до внешнего соединения, объединений и тому подобного. Но я могу лучше управлять им, используя кодирование с помощью LINQ, и, конечно, поддерживать его проще. Таблица, которую я использую, содержит как минимум 5 объединений, в сегменте eat union много внешних соединений. Подводя итог, тот человек, который написал этот запрос, слишком благочестивый, но я должен был его поддерживать.