Использует ли Entity Framework отражение и снижает производительность? - PullRequest
6 голосов
/ 22 марта 2011

В конечном итоге у меня есть две области, в каждой из которых есть несколько вопросов о Entity Framework, но позвольте мне дать небольшую справку, чтобы вы знали, в каком контексте я запрашиваю эту информацию.

На моей работе моя командапланирует полностью переписать структуру нашего приложения, чтобы мы могли придерживаться более современных стандартов.Эта перезапись включает в себя совершенно новый проект слоя данных.В этом проекте большая часть команды хочет использовать Entity Framework.Я тоже хотел бы использовать это, потому что я очень знаком с этим из моего использования в личных проектах.Однако один из членов команды категорически против этого, заявив, что Entity Framework использует рефлексию и убивает производительность.Его другой аргумент заключается в том, что EF использует сгенерированный SQL, который гораздо менее эффективен, чем хранимые процедуры.Я не очень знаком с внутренней работой EF, и мои поиски не нашли ничего чрезвычайно полезного.

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

Issue 1 Questions - Reflection

  1. Верно ли это в отношении EF, использующего отражение и снижающие производительность?
  2. Где EF использует отражение, если оно использует?
  3. Есть ли ресурсы, которые сравнивают производительность?Что-то, что я мог бы использовать для объективного сравнения технологий доступа к данным в .NET, а затем представить их моей команде?

Вопрос 2 Вопросов - SQL

  1. Каковы последствия этого?
  2. Можно ли использовать хранимые процедуры для заполнения объектов EF?
  3. Опять же есть некоторые ресурсы, которые сравнивают сгенерированные запросы с хранимыми процедурами, и чтопоследствия использования хранимых процедур для заполнения сущностей (если вы можете) были бы?

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

РЕДАКТИРОВАТЬ

Это все некоторые очень информативные ответы.Спасибо.Я собираюсь оставить этот вопрос без ответа на некоторое время, так что, возможно, будут предоставлены некоторые жесткие ссылки на статьи и другие внешние ресурсы.Возможно, этот вопрос поможет кому-то в будущем в моем затруднительном положении.

Ответы [ 7 ]

7 голосов
/ 22 марта 2011

Да, ему нравятся многие другие ORM (NHibernate) и полезные фреймворки (инструменты DI). Например, WPF не может работать без отражения.

Хотя последствия использования Reflection для производительности не сильно изменились за последние 10 лет, начиная с .NET 1.0 (хотя улучшения были улучшены), с более быстрым аппаратным обеспечением и общей тенденцией к удобочитаемости становится все меньше беспокойство сейчас.

Помните, что основной удар по производительности произошел во время , отражающего также связывание , которое считывает метаданные типа в xxxInfo (например, MethodInfo), и это происходит при запуске приложения.

Вызов отраженного метода определенно медленнее, но не считается большой проблемой.


UPDATE

Я использовал Reflector для просмотра исходного кода EF и Я могу подтвердить, что он интенсивно использует Reflection.

4 голосов
/ 22 марта 2011

Ответ на вопрос 1:

Вы можете точно посмотреть, что выводит EF, изучив сгенерированный файл Foo.Designer.cs.Вы увидите, что полученный контейнер не использует отражение, но интенсивно использует дженерики.

Вот места, в которых Entity Framework, безусловно, использует отражение:

  1. Expression<T> интерфейс используется при создании операторов SQL.Методы расширения в System.Linq основаны на идее деревьев выражений, которые используют типы в System.Reflection для представления вызовов функций и типов и т. Д.
  2. Когда вы используете хранимую процедуру, подобную этой: db.ExecuteStoreQuery<TEntity>("GetWorkOrderList @p0, @p1", ...)Entity Framework должен заполнить сущность и, по крайней мере, должен проверить, отслеживается ли предоставленный тип TEntity.

Ответ на вопрос 2:

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

Кроме того, вы, конечно, можете использовать хранимые процедуры или дажеВстроенный SQL со структурой сущностей, для запросов и для создания, обновления и удаления.

В сторону:

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

3 голосов
/ 22 марта 2011

Я могу прокомментировать вопрос 2 о сгенерированных EF-запросах, которые менее эффективны, чем хранимые процедуры.

По сути, да, иногда сгенерированные запросы являются беспорядочными и требуют некоторой настройки.Есть много инструментов, которые помогут вам исправить это, SQL Profiler, LinqPad и другие.Но в конце концов сгенерированные запросы могут выглядеть как дерьмо, но обычно они выполняются быстро.

Да, вы можете сопоставить сущности EF процедурам.Это возможно и позволит вам контролировать некоторые неприятные сгенерированные запросы EF.В свою очередь вы также можете сопоставить представления с вашими сущностями, позволяя вам контролировать то, как представления выбирают данные.

Я не могу думать о ресурсах, но должен сказать это.Сравнение с использованием хранимых процедур EF vs SQL - это яблоки с апельсинами.EF предоставляет надежный способ сопоставления вашей базы данных с вашим кодом напрямую.Это в сочетании с запросами LINQ to Entity позволит вашим разработчикам быстро создавать код.EF - это ORM, где процедуры хранения SQL не используются.

2 голосов
/ 22 марта 2011

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

Что касается хранимых процедур, они выполняются быстрее, чем простые старые запросы, но это преимущество часто перепродано.Основное преимущество заключается в том, что база данных будет предварительно компилироваться и сохранять план выполнения для каждой хранимой процедуры.Но база данных также будет кэшировать планы выполнения, которые она создает для простых старых запросов SQL.Так что это преимущество сильно зависит от количества и типа запросов, выполняемых вашим приложением.И да, вы можете использовать хранимые процедуры со структурой сущностей, если вам нужно.

1 голос
/ 22 марта 2011

Созданные Entity Framework SQL-запросы хороши, даже если они не совсем так, как ваш DBA написал бы вручную.

Однако генерирует полный мусор, когда речь идет о запросах по базовым типам.Если вы планируете использовать схему наследования Table-per-Type, и , то вы ожидаете запросов на базовые типы, тогда я рекомендовал бы действовать с осторожностью.

Для более подробного объясненияэтот странный недостаток, см. мой вопрос здесь .обратите особое внимание на принятый ответ на этот вопрос - возможно, это ошибка.

Что касается вопроса обдумывания - я думаю, что ваш коллега цепляется за соломинку.Маловероятно, что отражение будет основной причиной проблем с производительностью вашего приложения.

1 голос
/ 22 марта 2011

Я не знаю, использует ли EF отражение (я не верю, что оно делает ... Я не могу думать о том, какую информацию нужно было бы определить во время выполнения);но даже если это так, то что?

Reflection используется повсеместно в .NET (например, сериализаторах), некоторые из которых вызываются все время.

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


EDIT

СтатьяРик Страл о производительности отражения: .Net Reflection and Performance (старая, но все еще актуальная).

0 голосов
/ 23 марта 2011

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

Я считаю, что все эти "показатели производительностиПодобные "проблемы решаются правильно путем кэширования необходимой информации для отображенияВлияние производительности, вызванное отражением, вероятно, будет ничем по сравнению с сетевым взаимодействием с сервером, выполнением сложного запроса и т. Д.

Если мы говорим о производительности EF, проверьте эти два документа: Часть 1 и Ч.2 .В нем описывается некоторая причина, почему люди иногда думают, что EF очень медленный.

Являются ли хранимые процедуры быстрее, чем запросы EF?Мой ответ: я так не думаю.Основным преимуществом linq является то, что вы можете создать свой запрос в приложении.Это очень удобно, когда вам нужно что-то вроде фильтрации списка, разбиения по страницам и сортировки + изменения количества отображаемых столбцов, загрузки объектов с реализацией и т. Д. Если вы хотите реализовать это в хранимой процедуре, у вас будет или десятки процедур для различных конфигураций запросов, или выбудет использовать динамический sql.Динамический sql - это именно то, что использует EF.Но в случае EF этот запрос имеет проверку времени компиляции, что не относится к простому SQL.Единственное различие в производительности - это объем передаваемых данных при отправке всего запроса на сервер и при отправке только процедур и параметров exec.

Это правда, что запросы иногда очень странные.Особенно наследование порождает иногда плохие запросы.Но это уже решено.Вы всегда можете использовать пользовательскую хранимую процедуру или запрос SQL для возврата объектов, сложных типов или пользовательских типов.EF материализует результаты для вас, поэтому вам не нужно беспокоиться о читателях данных и т. Д.

Если вы хотите быть объективными при представлении Entity Framework, вы должны также упомянуть о его минусах.Entity Framework не поддерживает пакетную обработку команд.Если вам нужно обновить или вставить несколько объектов, каждая команда sql имеет свой собственный обходной путь к базе данных.Из-за этого вы не должны использовать EF для переноса данных и т. Д. Еще одна проблема с EF - это отсутствие зацепок за расширяемость.

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