Сравнение entity framework и dapper

Обновлено: 04.07.2024

Теория, лежащая в основе использования ORM, заключается в том, что он освобождает разработчиков от большей части утомительной и подверженной ошибкам работы по написанию кода для операций CRUD (создание, получение, обновление, удаление) с базами данных. Используя ORM, разработчики могут работать с классами, представляющими их бизнес-объекты, и просить ORM сохранять и извлекать их по мере необходимости.

Ветеран Open Source PostgreSQL выпускает выпуск 14 °

Новые функции включают поддержку темпоральных таблиц SQL Server (таблиц, в которых хранится история изменений данных); Поддержка столбцов JSON; улучшенная поддержка миграции (бизнес по обновлению базы данных из объектной модели в коде); и поддержка всех запросов, которые работают в EF 6.x. Также есть планы по улучшению поставщика Cosmos DB, в том числе для многомодельной службы базы данных Azure от Microsoft и полного поиска по произвольному тексту для SQLite и SQL Server.

Пытаюсь поймать Даппера

Производительность — еще одна большая проблема. Планы включают скомпилированные модели и улучшение работы EF Core с компоновщиками и AOT, где AOT является опережающей компиляцией. «Мы планируем достичь уровня производительности Dapper в тесте TechEmpower Fortunes», — заявил Ликнесс, добавив: «Это серьезная задача, которая, скорее всего, не будет полностью решена».

Элементы в шаблоне в ASP.Net Core, для быстрого добавления функций базы данных используйте Entity Framework

Недостаток KVM на серверах AMD дал вредоносным виртуальным машинам путь к захвату хоста •

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

ORM — это пример того, что разработчик Джоэл Спольски дублированный «дырявая абстракция».

По его словам, абстракция — это «упрощение чего-то гораздо более сложного, что происходит под покровом», а утечки представляют «вещи, от которых абстракция не может вас полностью защитить».

Спольски описал SQL, общий язык запросов к базе данных, как дырявую абстракцию, которая делает ORM дырявой абстракцией или дырявой абстракцией.

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

VMware начинает тестирование vSphere на сетевых ускорителях заказчиками.

Вторая проблема заключается в том, что ORM имеют свою сложность, которая может быть такой же плохой, как и сложность, от которой они пытаются вас защитить.

Если вы прочтете отношения «многие ко многим» в EF, вы можете сделать вывод, что синтаксис SQL JOIN не сложнее изучить и более точен в использовании. Контраргумент состоит в том, что идеальная ORM могла бы генерировать лучше оптимизированный SQL, чем может достичь большинство разработчиков.

Как разработчики оптимизируют EF в своих приложениях? Отчасти, научившись извлекать из этого максимум пользы; частично путем проверки SQL, который генерирует EF. Это означает, что опытным пользователям EF все еще необходимо понимать SQL.

Сноска

[Продолжение] Почему через 5 лет мы должны переходить с Entity Framework на инструменты Dapper?

Последняя статья получила более 140 комментариев, чего мы не ожидали.

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

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

Эта статья посвящена Dapper.

Dapper настолько прост, что у нее есть только 3 справочные функции:

  1. Выполните запрос и сопоставьте результат со строго типизированным списком
  2. Выполните запрос и сопоставьте результаты со списком динамических объектов
  3. Выполнить команду без возврата результатов

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

Некоторые люди говорят, что простота на самом деле означает сложность, и это правда.

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

Ниже я расскажу о проблемах, возникших при миграции AppBoxPro с EntityFramework на Dapper, и о решениях, которые также включают мой небольшой пакет, надеюсь, вам понравится.

Ниже приведен снимок экрана разработки проекта AppBoxPro.Dapper:


Напоминание: в конце статьи загрузите весь исходный код AppBoxPro.Dapper стоимостью 109 юаней бесплатно, только на два дня с 10.09.2018, не забудьте!

Модельное соглашение

У нас есть два соглашения о модели:

1. Интерфейс IKeyID

2. Функция NotMapped

Взгляните на объявление модели User:

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

Функция NotMapped указывает, что этот атрибут не имеет сопоставления с базой данных и используется только как атрибут в памяти, что обычно имеет две цели:

1. Свойства, связанные с таблицей, такие как свойство UserDeptName в модели User.Свойство Name таблицы Dept может быть сопоставлено с ним путем внутреннего соединения во время извлечения из базы данных.

2. Значения, вычисленные в памяти, такие как TreeLevel, Enabled, IsTreeLeaf в модели Dept, используются для определения иерархии узлов и атрибутов узлов в таблице дерева моделирования.

Один запрос на одно подключение к базе данных

Если вы посмотрите документацию Dapper, вы найдете общий фрагмент кода операции:

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

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

При таком написании вы будете спотыкаться, что совсем нехорошо.

Затем уничтожьте соединение в конце запроса в Global.asax:

После этой простой инкапсуляции код для получения списка пользователей выше может быть написан напрямую:

Получать объекты по ID

В проектах нам часто может потребоваться получить объекты по идентификатору. Реализация в Dapper очень проста:

Но поскольку эта операция часто используется, нам может потребоваться скопировать и вставить несколько раз и изменить только несколько строк.

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

Вы можете увидеть в нем комментарии, соглашение от класса модели к таблице базы данных: Модель пользователя соответствует имени таблицы базы данных users.Это соглашение помогает нам использовать универсальные типы и параметры строгого типа (User) без передачи строк (users)).

После этого преобразования намного проще получать объекты по идентификатору:

Отображение связанной страницы (редактирование пользователем):


Вставить и обновить

Вставки и обновления - обычные операции с базой данных. Например, работа с элементами меню включает в себя вставку и обновление таблицы меню:

Сначала инициализируйте объект модели Menu, затем получите значение атрибута со страницы и назначьте его объекту модели и, наконец, выполните операцию вставки с помощью метода Execute, предоставленного Dapper.

Соответственно, операция обновления должна сначала получить объект модели меню через идентификатор меню, а затем обновить базу данных:

Вышеупомянутые операции вставки и обновления доставляют два неудобства:

1. Оператор SQL должен содержать несколько атрибутов для обновления, которые легко пропустить и написать ошибки.

2. Когда вставленные и обновленные списки атрибутов совпадают, написание полностью отличается, что неудобно копировать и вставлять.

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

Вышеупомянутая функция получает список атрибутов (GetProperties ()) соответствующего класса модели (instance.GetType ()) экземпляра через отражение, затем фильтрует атрибут ID и атрибут с аннотацией NotMapped и, наконец, возвращает массив атрибутов.

Инкапсуляция операции вставки:

Метод ExecuteInsert принимает следующие параметры:

1. Введите T: получите имя таблицы базы данных по имени класса модели, которое является соглашением об именах.

2. instance: экземпляр модели, который необходимо вставить в соответствующую таблицу данных.

3. fields: это переменный параметр. Если параметр fields не передан, функция GetReflectionProperties, определенная ранее, получит список всех атрибутов класса модели.

Наконец, после простого объединения строк вы можете легко сгенерировать необходимые операторы SQL и выполнить команду Dapper Execute для вставки данных.

Используя метод ExecuteInsert, мы можем упростить указанную выше операцию вставки до:

Или просто напишите это так:

Это очень удобно?

Точно так же операция обновления аналогична, за исключением того, что логика объединения строк SQL во время инкапсуляции немного отличается:

Используя инкапсулированный метод ExecuteUpdate, описанную выше операцию обновления можно упростить до:

Отображение связанной страницы (страница роли пользователя):


Вернуть идентификатор автоинкремента после вставки

Иногда после вставки новых данных нам необходимо немедленно получить атрибут ID вновь вставленных данных, чтобы облегчить последующие операции с базой данных. Для этого требуется изменить приведенный выше ExecuteInsert, добавив следующий оператор SQL после оператора вставки:

Вышеупомянутый оператор SQL применим только к базе данных MySQL. Конечно, нетрудно поддерживать другие базы данных, что будет объяснено позже. Обновленный метод ExecuteInsert выглядит следующим образом:

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

Фильтрация, пейджинг и сортировка

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

Это совершенно не нужно!

Поскольку разбиение на страницы и сортировка являются полностью стандартными операторами SQL, Dapper не несет за это ответственности.

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

1. Добавьте условия фильтрации (например, соответствие ключевых слов в имени и перечисление только включенных строк . )

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

3. Получить данные текущей страницы.

Ниже приведен код фильтрации, разбиения на страницы и сортировки страницы списка ролей в AppBoxPro, который мы можем сразу увидеть:

Вышеупомянутое включает три важных настраиваемых класса и функции:

1. WhereBuilder: Мы инкапсулировали простой класс, основная цель которого - объединить вместе условия запроса, параметры условий и операторы SQL 3.

2. Счетчик: используется для возврата общего количества записей.

3. SortAndPage: используется для разбиения по страницам и сортировки.

Сначала посмотрите на WhereBuilder:

1. _wheres: соответствует предложению where в SQL.

2. _parameters: соответствует фактическим параметрам, используемым в предложении where.

3. _fromSql: Если этот атрибут опущен, имя таблицы базы данных, с которой необходимо работать, является производным от имени класса модели.Для сложных запросов, требующих ассоциации таблиц, вам необходимо установить этот параметр, который будет подробно объяснен позже.

Определение функции Count:

Определение функции SortAndPage:

Вышеупомянутая инкапсуляция очень проста, есть всего три строки кода для обработки подкачки:

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

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

Таблица ассоциации

На странице онлайн-списка пользователей для определенного пользователя мы должны не только указать время входа в систему, время последней операции, IP-адрес, но также имя пользователя и имя пользователя на китайском языке.

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

Отображение связанной страницы (список пользователей):


Сделка

В Dapper есть два типа поддержки транзакций: один - передавать объекты транзакции непосредственно в Query или Execute, а другой более простой.

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

Отображение связанной страницы (разрешения ролей):


Анонимные параметры (объекты и массивы)

Dapper поддерживает удобный ввод анонимных параметров, которые мы уже много раз видели раньше, например, следующий код для обновления ролей пользователей:

Мало того, Dapper также поддерживает многократное выполнение команды, просто передавая анонимный массив.

В AppBoxPro существует множество сценариев приложений, например, предыдущий код для обновления ролей пользователей:

Здесь массив динамических объектов получается с помощью выражения Select.

В ConfigHelper у нас также есть сценарий ручного создания анонимного массива для обновления нескольких строк данных в таблице конфигураций:

Поддержка нескольких баз данных

Поддержка нескольких баз данных действительно несложна: из двух поддерживаемых нами баз данных, MySQL и SQLServer, лишь некоторые требуют особого обращения.

1. Для подключения к базе данных мы можем сгенерировать различные экземпляры IDbConnection на основе ProviderName.

Сначала посмотрите на раздел конфигурации, связанный с базой данных, в Web.config:

Тогда есть расширение GetDbConnection:

2. Получите новый идентификатор строки после вставки

3. Обработка подкачки базы данных, обновленная функция SortAndPage:

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

Эта статья в основном описывает проблемы, возникающие при переходе с Entity Framework на Dapper, и простой пакет, который мы предоставили, надеюсь, вам понравится. Чтобы

Загрузите весь исходный код AppBoxPro.Dapper стоимостью 109 юаней бесплатно, только на два дня с 11.09.2018, не забывайте!

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

  1. AppBoxPro (версия Entity Framework)
  2. AppBoxPro (версия Dapper)
  3. AppBoxMvc (версия Entity Framework)
  4. AppBoxMvc (версия Dapper)

Интеллектуальная рекомендация

Поверните строку в целые числа

Тема Описание Преобразуйте строку в целое число (реализация функции integer.valueof (строка), но строка не совпадает 0), требуя функции библиотеки, которая нельзя использовать для преобразования целых.

Docker создает репликацию Redis Master-Slave

Centos установить докер быстрый старт докера Создать Dockerfile Поместите файл на сервер Linux, создайте папку / usr / docker / redis и поместите его в этот каталог Выполните следующий код в каталоге .


Установка GateOne на новом CentOS7

Установка GateOne на новом CentOS7 В последнее время исследуются такие инструменты, как WebSSH2, в настоящее время требуется встроить терминал ssh в веб-приложение и найти GateOne. GateOne - это веб-в.


Примечания к исследованию Qt4 (5), QWaitCondition of QThread Learning


Практические занятия: решения проблем системы управления обучением

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

Вам также может понравиться


искробезопасная практика (5) обратный индекс

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


Решение центра тяжести неправильного многоугольника

Справочник статей Во-первых, решение центра тяжести неправильных многоугольников 1.1 Метод расчета треугольника центра тяжести 1.2 Метод расчета площади треугольника 1.3 Метод расчета площади полигона.

У меня EF с LINQ с SQL Server в моем проекте долгое время.

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

Прежде всего, я проверил с запросом, который имеет много Join. Я получил почти такие же результаты между Dapper и Процедурой и EF. Тогда я решил сделать тест с одной простой таблицей без отношений.

У меня есть таблица ZipCodes. Есть 43200 записей.

Я провел тестирование по 1 000 записей, 10 000 записей и 43200 записей, используя EF, Dapper, хранимую процедуру и запрос в SQL Server.

Запрос в SQL Server со временем

В коде я использую секундомер

Результаты: (в миллисекундах)

Разница между EF, Dapper и хранимой процедурой очень мала. Почему это так?

И почему запрос в SQL Server так быстр, а запросы из кода в 15-70 раз медленнее?

Это нормально или нет?

спросил(а) 2019-03-17T12:49:00+03:00 2 года, 8 месяцев назад

Код, использующий EF, демонстрирующий проблемы с производительностью, не будет волшебным образом работать быстрее с Dapper или ADO + Sprocs. Чтобы разобраться в проблеме с производительностью, вам необходимо исследовать и устранить причины проблем с производительностью.

На верхнем уровне эти проблемы производительности связаны с двумя основными проблемами.

    Загрузка слишком большого количества данных. Загрузка данных слишком часто.

Ключевые вещи, на которые я обращаю внимание: (для начала, есть намного больше предметов, но это большие победы)

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

    Метод поиска: подключите профилировщик SQL к базе данных, с которой работает только ваш отладочный экземпляр приложения. (Т.е. локальная БД) Симптом: просмотр большого количества запросов "SELECT TOP (1). " после основного запроса для загрузки одного объекта или коллекции. Исправление: быстрое решение состоит в том, чтобы ввести .Include() нагрузки ( .Include() ) для загрузки этих коллекций. Лучшее решение - использовать .Select() чтобы просто загрузить свойства, необходимые для рассматриваемого кода.

.ToList() : неулокальные вызовы .ToList() могут вызывать огромные проблемы с производительностью по мере взросления систем, поскольку разработчики столкнулись с проблемой EF, которая была решена путем вызова .ToList . Обычно они появляются, когда разработчики пытаются вызвать метод внутри выражения .Where() или .Select() . EF не может понять, что они передают эквивалент SQL, поэтому добавление .ToList() преобразует его в Linq2Object, и "та-да" работает!

    Метод .ToList() экземпляры .ToList() и .ToList() все случаи, когда вы найдете .ToList() перед .Select() или .Where() и т.д. Симптом: удаление дополнительного .ToList() вызывает ошибку EF. Исправлено: Проверьте, имеет ли функция-нарушитель эквивалент DbFunctions. Распространенной проблемой является работа с функциями DateTime, которые можно найти в DbFunctions. В других случаях найдите нарушающую функцию и создайте модель представления для ожидаемых данных, которые выбираются, затем создайте свойство для запуска функции в модели представления.

Пагинация на стороне клиента + сущности: еще один грех разработки без надлежащих выборочных данных. Написаны запросы, которые эффективно возвращают все данные без учета общего количества записей. Данные отображаются на стороне клиента в сетке с разбиением на страницы, которая "работает", но на самом деле очень медленно. Он работал нормально, когда в базе данных было только 200 строк, но теперь сканирует с 50000. (и будет только хуже)

    Метод охоты: посмотрите на любой метод API/Controller, который возвращает коллекции. Используют ли эти запросы .ToList() или .Skip() + .Take() ? Возвращают ли эти методы объекты или просматривают модели? Симптом: листы с нумерацией страниц загружаются очень медленно. После загрузки переключение страниц происходит быстро. Исправлено: вызовы из элементов управления нумерацией страниц должны быть изменены, чтобы использовать нумерацию на стороне сервера. Это означает отправку на сервер вызовов сортировки, размера страницы и номера страницы. Таким образом, запросы EF могут быть более эффективными для загрузки только того количества строк, которое должно отображаться элементом управления. Код также должен возвращать модели просмотра для результатов поиска, которые представляют только отображаемые столбцы, и ключи, необходимые для загрузки полной сущности по требованию. (например, когда пользователь щелкает, чтобы открыть запись.) Объекты могут быть тяжелыми, когда вам нужно только отобразить несколько полей.

Индексация базы данных: была ли база данных отслежена и поддерживается? Существуют ли индексы и ведение индексов? Для SQL Server выполняется ли резервное копирование базы данных с сокращением журнала Tx? Внедрения Code First изобилуют этими проблемами, когда система запускается без учета резервной базы данных. По мере роста систем не уделяется внимания базе данных, поддерживающей ее.

Размышления о разработке программного обеспечения и информационных систем

То, что действительно важно, но чему нигде не учат

Сравнение производительности EF 7, Dapper и ADO.

Замечу, что цифры измерялись для локальных подключений.

Мы точных измерений не проводили, но порядки те же. Даппер в 4 раза быстрее, чем EF последней версии (с применением AsNoTracking для отключения кэширования, и это отдельная тема). И при этом разница в производительности между даппером и ADO несущественна, но даппер добавляет маппинг результата на объекты.

Posts from This Journal by “базы данных” Tag


Видео: Основы SQL

Видеокурс от Андрея Созыкина "Основы SQL" на примере PostgreSQL. 1. Базы данных и SQL 2. Оператор SELECT 3. Фильтрация данных в SQL: WHERE…

Ссылка: Настройка отказоустойчивого кластера MongoDB

Несколько статей по организации отказоустойчивого кластера MongoDB. Для начала, общие сведения: Replication in MongoDB Настройки ReplicationSet:…

Ссылка: Настройка отказоустойчивого кластера PostgreSQL

Статьи на английском языке, но, надеюсь, это не вызовет проблем. How to Automate PostgreSQL 12 Replication and Failover with repmgr – Part 1 How…


Модели данных в информационной системе

Сегодня я хотел бы поговорить немного о моделях данных в информационной системе. Причём поговорить о них именно в разрезе обработки данных системой…


Повышение квалификации: Проектирование высоконагруженных систем

Александр Быков говорит о том же, о чём не устаю говорить я своим коллегам: качество реализуемых систем имеет многоуровневые зависимости от…

Ссылка: Руководство по MongoDB

Руководство по MongoDB MongoDB это кросс-платформенная, документно-ориентированная СУБД, которая обеспечивает высокую производительность и лёгкую…

Тринадцатый семинар для молодых аналитиков

Очень тяжёлая тема для понимания - диаграмма классов. И тяжёлая не только с точки зрения понимания самой диаграммы, но и с точки зрения её…


Анализ хранилищ данных

Существуют разные типы хранилищ данных. Наиболее распространённые хранилища корпоративных данных – файловые и реляционные (на основе…


SQL: что тормозит удаление записей

В реляционных БД есть 8 основных причин тормозов на DELETE (не считая кривых запросов): большое количество индексов в таблице, из которой…

Читайте также: