LINQ. Хотите добавить предложение where динамически. Я боюсь ввода-вывода в БД

Я использую веб-API ASP.NET и шаблон репозитория.
И я хочу динамически добавлять предложение where. Нравится,

//controller
  static readonly ICustomerRepository repository = new CustomerRepository();
  //
 var result = repository.GetAll();

 if (form['name'] != null) result.Where( p => p.custName.Contains( form['name'].toString() ) );
 if (form['attribute1'] != null) result.Where( p => p.attribute1.Equals( form['attribute1'].toString() ) );
 return result;
//

ИО не боятся?


person taiji    schedule 30.08.2012    source источник
comment
ИО не боятся? - Не могли бы вы перевести это предложение? Совершенно непонятно, что это значит.   -  person Daniel Hilgarth    schedule 30.08.2012
comment
больше деталей / больше спецификации. чтобы предотвратить неправильное толкование, не используйте ярлыки.   -  person varg    schedule 30.08.2012
comment
IOs, я имею в виду доступ к базе данных, SQL-запрос к базе данных. Я боюсь выполнять SQL несколько раз.   -  person taiji    schedule 31.08.2012


Ответы (4)


ИО не боятся?

Не совсем понятно, что вы имеете в виду, но запрос будет отправлен в базу данных только тогда, когда вы попытаетесь его выполнить, что, предположительно, находится в каком-то коде, который вызывает ваш метод. Это не похоже на то, что он будет выполняться один раз для GetAll, затем один раз для первого предложения Where, затем один раз для второго предложения Where. Все это будет упаковано в один запрос, когда вы начнете получать данные из файла IQueryable<>.

person Jon Skeet    schedule 30.08.2012
comment
Спасибо. запрос будет отправлен в базу данных только тогда, когда вы попытаетесь его выполнить, я просто хочу это знать. - person taiji; 31.08.2012
comment
Джон, ты действительно хорошо справился с IO здесь ;-) - person Filip W; 31.08.2012

Если вам нужно несколько предложений where, взгляните на этот вопрос, который я задал: Объединить запросы LinQ

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

person BugFinder    schedule 30.08.2012
comment
Спасибо. Я прочитал ссылку. Есть ли разница в добавлении предложения where напрямую (мой шаблон) и в добавлении предложения where с использованием фильтра (ссылка Ответ)? - person taiji; 31.08.2012
comment
Да, вы получаете все записи, затем удаляете некоторые, затем удаляете еще, вы выполняете дополнительную обработку ... тогда как, если вы скажете ему сделать это за один раз, это больше похоже на получение материала, который я хотел. - person BugFinder; 31.08.2012
comment
Я думаю, что способ ответа на ссылку такой же, как и несколько раз в строке цикла foreach foundfiles.Where(filterToApply). Что-то не так, если моя идея? - person taiji; 31.08.2012

Если вы обращаетесь к data-base, почти всегда есть доступ IO, если нет какой-либо настройки кэширования памяти. Так что это зависит от того, как вы управляете data-base. Но в целом data-base настроен на высокопроизводительный IO доступ, поэтому, пока вы не собираетесь писать крупномасштабное приложение, лично я не стал бы беспокоиться о накладных расходах IO на простые запросы, подобные этому.

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

person Tigran    schedule 30.08.2012
comment
хм, возможно ли, что IO означает «InvalidOperation» в этом случае? - person varg; 30.08.2012
comment
Мне кажется, что ОП говорит о доступе к хранилищу ввода-вывода. - person Tigran; 30.08.2012
comment
Извините, мой вопрос неясен. Я хочу знать, когда выполняется запрос sql. - person taiji; 31.08.2012

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

Однако вам нужно присвоить результат чему-то, иначе вы просто будете создавать выражения и отбрасывать их:

var result = repository.GetAll();

if (form['name'] != null) {
  result = result.Where( p => p.custName.Contains( form['name'].toString() ) );
}
if (form['attribute1'] != null) {
  result = result.Where( p => p.attribute1.Equals( form['attribute1'].toString() ) );
}
return result; // or return result.ToList();

Подумайте, хотите ли вы запустить фактический запрос в конце метода, добавив ToList, или хотите вернуть выражение, которое будет выполняться кодом, вызывающим метод.

person Guffa    schedule 30.08.2012
comment
Спасибо. Я лучше понимаю LINQ. - person taiji; 31.08.2012