Загружает ли ORM (Linq-SQL EF) весь набор данных из таблицы? - PullRequest
0 голосов
/ 16 апреля 2011

Вопрос, связанный с тем, как ORM (Linq to SQL, EF 4) обрабатывает загрузку данных. Загружен ли весь набор данных, если так, можем ли мы предотвратить загрузку всего набора данных и загрузить подмножество? Например, при создании экземпляра контекста и запросе кажется, что возникнет огромная проблема с производительностью, если будут возвращены все данные (сотни тысяч записей) по сравнению с созданием соединения, выполнением процедуры для данного подмножества данных и запросом для этого подмножества данных. Я не видел много тем, обращающихся к этому, заранее спасибо!

Ответы [ 2 ]

4 голосов
/ 16 апреля 2011

Нет, это не так, поскольку Linq to Sql / Eft проанализирует запрос, чтобы создать оптимизированный sql-запрос для извлечения ваших данных, поскольку считается, что неправильное использование метода расширения (который вызывает GetEnumrator()) или запроса может в конечном итоге загрузка всех элементов из таблицы.

Злоупотребление методами расширения, которые вызывают GetEnumerator()

context.Books.ToList().Where(somePredicate).Select(someSelector);

Это приведет к загрузке всей таблицы Books, поскольку ToList() вызовет запрос sql для извлечения всех объектов Book. Оттуда вы Where и Select фактически работаете над Linq для объектов, а не Linq To Sql / Entities.

context.Books.Where(somePredicate).Select(someSelector).ToList();

Простое нажатие .ToList() в конце оператора приведет к тому, что EF проанализирует запрос в действительный SQL-запрос и получит часть ваших книг при вызове .ToList().

Злоупотребление Func<T, bool>

Рассмотрим следующее,

Func<Book, bool> predicate = b=>b.Id == 3;
context.Where(predicate).ToList();

Теперь это выглядит совершенно корректно, однако, как только вы запустите запрос, вы обнаружите, что контекст загружает все Books, что дает? Проще говоря, EF не может проанализировать предикат Func<T, bool> на допустимый синтаксис sql, поскольку Func<> является просто делегатом. Эта простая ошибка может привести к тому, что EF загрузит все Книги в контекст, а затем запустит Linq to Objects для загруженных Книг.

Expression<Func<Book, bool>> predicate = b=>b.Id == 3;
context.Where(predicate).ToList();

Теперь здесь мы собираемся использовать Expression<Func<Book, bool>>, который является просто деревом выражений, EF знает, как анализировать дерево выражений, и способен создать действительный оператор SQL, который загружает только один Book с Id из 3 .

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

0 голосов
/ 16 апреля 2011

Если я понимаю ваш вопрос, Linq 2 Sql загружает не все в наборе данных.После того как вы создадите свой контекст и создадите оператор sql linq 2, будут извлечены только те таблицы, на которые есть ссылки в вашем выражении, если вы явно не скажете dataContext загружать связанные таблицы с использованием DataLoadOptions.

Теперь, если вы говорите опейджинг, используйте Skip and Take.

Кто-то другой может подключиться к EF, поскольку у меня нет особого опыта в этом, но я не могу себе представить, что это будет слишком по-другому.Мне нравится Linq 2 sql, и это было достаточно быстро для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...