Недавно увидел очень хороший способ уложить сайт с помощью LINQ. Программист на работе написал очень хорошую строку кода в которой прямо в методе Where написал C# функцию, которая должна была разбирать имя домена.
.NET не может оптимизировать такие вещи и выполнять из на сервере, поэтому вынужден будет вытащить все данные из базы, а потом для каждой строки выполнить C# функцию.
Если любите LINQ для доступа к базе данных, то разбивайте свои Where методы на составляющие.
.Where(здесь фильтр без использования C#)
.ToArray()
.Where(а вот здесь уже какой угодно фильтр)
В этом случае первый Where будет LINQ to SQL (или как он там называется) и будет выполнен на SQL сервере, а второй уже к коллекции и будет выполнен на сервере приложений. Второй Where получит меньше данных и не будет обрабатывать все строки.
Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым
Если программист работал с интерфейсом IQueryable, то он бы получил ошибку, что условие не может транслироваться в SQL. По всей видимости он работает с IEnumerable (прежде чем фильтровать использует один из методов: ToArray(), ToList(), AsEnumerable(), и т.д.) и тут уже не важно какой будет фильтр, вначале все будет тянуться из базы, а потом уже будет применяться фильтр.
Ты прямо поставил меня в тупик. Как он увидит ошибку, если у него есть код:
_context.Folders.Where(r => GetDomain(r.FolderID));
Что такое _context ясно. Что такое Folders - это таблица в базе данных. GetDomain пусть выглядит как C# функция вот в таком виде:
bool GetDomain(int test) {
return false;
}
Такой код компилируется на ура.
Скомпилируется, то на ура, но при первом вызове упадет с ошибкой вида:
The specified method 'method name' on the type 'type name' cannot be translated into a LINQ to Entities store expression.
Это произойдет при условии, что Folders - это IQueryable, а не IEnumerable.
Если человек начинает работать с LINQ to Entities, разницу между IQueryable и IEnumerable, он должен понимать.
Ваш код так будет работать всегда(при этом вытягивая все значения таблицы), если его переписать вот так:
_context.Folders.ToList().Where(r => GetDomain(r.FolderID));
Посмотрите внимательно, как был записан первоначальный запрос у вас на работе, наверняка работа велась с интерфейсом IEnumerable.
Я проверю позже, как он был написан. Но я бы твой пример немного изменил все же
.Where(здесь фильтр без использования C#)
.ToArray()
.Where(а вот здесь уже какой угодно фильтр)
Да все верно, именно так и нужно делать. Я в своем примере хотел показать, как могло быть в вашем случае на работе.
Да, это чудо природы вызвал ToArray() перед Where. Я это упустил. Я в Linq2Sql не спец, потому что не люблю его. Я Linq использую только к массивам, а не к базам данных
Mihail, pojaluista, ne obzovite svoih robotnikov. Kak mojno nazvati cheloveka chudom prirodi za odnu malenikuyu oshibku ? Vse mi delaem oshibki, prichem postoyanno. Ponimayu vi mojet biti znoete bolishe drugih, no ne vse je takoe kak vi. Pojaluista poimite mne pravelino, nichego plohovo ne hotel (naprotiv ocheni silino uvajayu za knigi), prosto vigledit ne krasivo. Mojet ya vas nepravelino ponyal, togda igvenite menya, russkii ne rodnoi moi yazik.
Я стараюсь ни о ком плохо не писать. В данном случае у меня просто отношение к этому человеку не очень хорошее. Я действительно понимаю, что все могут делать ошибки, но этот парень просто любит выпендриваться и критиковать других. Ему постоянно не нравится, как другие пишут код и он постоянно хочет все переписать. Меня это бесит. И ладно если бы он действительно был реально отличным программистом и писал крутой код. Кроме его я больше никого в жизни так вот не называл.
Спасибо, очень помог
Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.