Подходит ли Entity Framework для сайтов с большим трафиком?

176

Является ли Entity Framework 4 хорошим решением для общедоступного веб-сайта с потенциально 1000 посещений в секунду?

В моем понимании, EF - жизнеспособное решение для в основном небольших веб-сайтов или веб-сайтов интрасети, но его было бы нелегко масштабировать для чего-то вроде популярного веб-сайта сообщества (я знаю, что SO использует LINQ to SQL, но ... Мне бы хотелось больше примеров / доказательств. ..)

Сейчас я стою на распутье либо выбора чистого подхода ADO.NET, либо EF4. Считаете ли вы, что повышение производительности труда разработчиков с EF стоит потери производительности и детального доступа к ADO.NET (с хранимыми процедурами)? Какие-нибудь серьезные проблемы, с которыми мог бы столкнуться вебсайт с высоким трафиком, использовал ли это EF?

Заранее спасибо.

niaher
источник
1
Вы не понимаете масштабирование. Масштабирование означает получение 10-кратной пропускной способности при добавлении 10-кратной пропускной способности. Почему EF предотвратит это? Это добавляет постоянные накладные расходы к любой рабочей нагрузке базы данных.
usr

Ответы:

152

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

Если вам не нужно переключаться между поставщиками баз данных и различными форматами таблиц для каждого клиента, и если ваши данные в основном читаются , и если вам не нужно иметь возможность использовать одну и ту же модель в EF, SSRS , ADO.NET Data Services и т. Д. - тогда, если вы хотите абсолютную производительность в качестве ключевой меры, вы могли бы сделать гораздо хуже, чем смотреть на безрассудство . В наших тестах, основанных как на LINQ-to-SQL, так и на EF, мы обнаружили, что EF значительно медленнее с точки зрения производительности необработанного чтения, предположительно из-за уровней абстракции (между моделью хранения и т. Д.) И материализации.

Здесь, в SO, мы навязчиво навязываем необработанную производительность, и мы рады, что разработчики потеряли некоторую абстракцию, чтобы набрать скорость. Таким образом, наш основной инструмент для запросов к базе данных - безупречный . Это даже позволяет нам использовать нашу уже существующую модель LINQ-to-SQL, но просто: она работает намного быстрее. В тестах производительности это, в сущности, та же производительность, что и при написании всего кода ADO.NET (параметры, средства чтения данных и т. Д.) Вручную, но без риска ошибочного ввода имени столбца. Тем не менее, он основан на SQL (хотя он рад использовать SPROC, если это выбранный вами яд). Преимуществом этого является то , что не существует не дополнительная обработка участвует, но это система для тех , кто любит SQL. Что я считаю: неплохая вещь!

Типичный запрос, например, может быть:

int customerId = ...
var orders = connection.Query<Order>(
    "select * from Orders where CustomerId = @customerId ",
    new { customerId }).ToList();

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

Обратите внимание, что в этом ответе я не говорю, что EF не подходит для работы с большими объемами; просто: я знаю, что брезгливость до этого.

Марк Гравелл
источник
25
+1 за щегольство. Использование сложного ORM для чтения моделей просто не нужно. Подход, который мы сейчас используем, состоит в том, чтобы использовать ORM для нашей модели предметной области (где на самом деле полезные вещи ORM полезны) и более привлекательный для нашей модели чтения. Это делает для супер быстрых приложений.
2
@Marc, спасибо за отличный ответ - наконец-то я могу с уверенностью принять решение! Обязательно рассмотрим Dapper более подробно позже. Действительно нравится, как это только один файл :)
3
Я написал свой собственный ОРМ. Это медленно. Я посмотрел на щеголя и мне понравилось. Теперь я использую dapper для всех моих чтений и свой ORM для вставок (который поддерживает FK, транзакции и все хорошее). Это самый простой и читаемый код, который я когда-либо писал.
2
@ acidzombie24 dapper поддерживает транзакции, а часть contrib dapper (не являющаяся частью развертывания nuget) получает опции вставки и т. д. Просто упомяну для полноты. Я рад, что Dapper был под рукой.
Марк Гравелл
1
@anyname Я никогда не делал видеокурс на любую тему; Есть несколько видео, но не мной. Я склонен быть человеком с письменным словом
Марк Гравелл
217

Вопрос «какой ORM мне следует использовать» действительно нацелен на вершину огромного айсберга, когда речь идет об общей стратегии доступа к данным и оптимизации производительности в крупномасштабном приложении.

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

  1. Проектирование и поддержка баз данных

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

    Если вы не используете правильные методы нормализации, ваш сайт обречен. Если у вас нет первичных ключей, почти каждый запрос будет медленным. Если вы пользуетесь хорошо известными анти-шаблонами, такими как таблицы для пар «ключ-значение» (AKA Entity-Attribute-Value) без уважительной причины, вы увеличите количество физических операций чтения и записи.

    Если вы не воспользуетесь возможностями, которые предоставляет вам база данных, такими как сжатие страниц, FILESTREAMхранение (для двоичных данных), SPARSEстолбцы, hierarchyidдля иерархий и т. Д. (Все примеры SQL Server), то вы не увидите ничего рядом с производительность, которую вы могли видеть.

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

  2. Eager vs. Lazy Loading

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

    Это не хорошо или плохо, скорее это зависит от того, что на самом деле будет сделано с данными, и от того, сколько вы знаете заранее. Иногда ленивая загрузка абсолютно правильная вещь. Например, NHibernate может решить вообще ничего не запрашивать, а просто сгенерировать прокси для определенного идентификатора. Если все, что вам когда-либо нужно, это само удостоверение личности, зачем ему просить больше? С другой стороны, если вы пытаетесь распечатать дерево каждого отдельного элемента в трехуровневой иерархии, отложенная загрузка становится операцией O (N²), что крайне негативно сказывается на производительности.

    Одним из интересных преимуществ использования «чистого SQL» (то есть необработанных запросов / хранимых процедур ADO.NET) является то, что оно в основном заставляет вас задуматься о том, какие именно данные необходимы для отображения любого экрана или страницы. ORMs и функция отложенной загрузки не помешать вам делать это, но они действительно дают вам возможность быть ... ну, лениво , и случайно взрываются количество запросов вы исполняете. Таким образом, вы должны понимать свои возможности загрузки ORM и всегда быть бдительными в отношении количества запросов, которые вы отправляете на сервер для любого данного запроса страницы.

  3. Кэширование

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

    Кэш-память L1 довольно непрозрачна в L2S и EF, вы должны верить, что она работает. NHibernate более четко об этом ( Get/ Loadvs. Query/ QueryOver). Тем не менее, до тех пор, пока вы пытаетесь запросить по идентификатору как можно больше, у вас все будет в порядке. Многие люди забывают о кеше L1 и многократно просматривают одну и ту же сущность с помощью чего-то, кроме ее идентификатора (то есть поля поиска). Если вам нужно сделать это, вы должны сохранить идентификатор или даже весь объект для будущих поисков.

    Также есть кэш 2-го уровня («кеш запросов»). NHibernate имеет этот встроенный. Linq to SQL и Entity Framework имеют скомпилированные запросы , которые могут значительно снизить нагрузку на сервер приложений, компилируя само выражение запроса, но оно не кэширует данные. Похоже, что Microsoft считает это проблемой приложения, а не доступа к данным, и это является основным слабым местом как L2S, так и EF. Излишне говорить, что это также слабое место «сырого» SQL. Чтобы получить действительно хорошую производительность с любым другим ORM, кроме NHibernate, вам нужно реализовать свой собственный фасад кэширования.

    Есть также «расширение» кеша L2 для EF4, что нормально , но на самом деле не является полной заменой кеша уровня приложения.

  4. Количество запросов

    Реляционные базы данных основаны на наборах данных. Они действительно хороши в создании больших объемов данных за короткий промежуток времени, но они не так хороши с точки зрения задержки запросов, потому что в каждой команде есть определенные накладные расходы. Хорошо спроектированное приложение должно играть в сильные стороны этой СУБД и стараться минимизировать количество запросов и максимизировать объем данных в каждом.

    Теперь я не говорю, чтобы запрашивать всю базу данных, когда вам нужна только одна строка. То , что я хочу сказать, если вам нужно Customer, Address, Phone, CreditCardи Orderряды все в то же время для того , чтобы служить одной страницы, то вы должны задать для них все в то же время, не выполняете каждый запрос по отдельности. Иногда это хуже, вы увидите код, который запрашивает одну и ту же Customerзапись 5 раз подряд, сначала чтобы получить Id, потом Name, потом EmailAddress, потом ... это смехотворно неэффективно.

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

    Это может звучать как здравый смысл, но часто очень легко потерять все запросы, которые выполняются в различных частях приложения; ваш провайдер членства запрашивает таблицы пользователей / ролей, ваше действие «Заголовок» запрашивает корзину покупок, ваше действие «Меню» запрашивает таблицу карты сайта, ваше действие «Боковая панель» запрашивает список рекомендуемых продуктов, а затем, возможно, ваша страница разделена на несколько отдельных автономных областей, которые запрашивайте таблицы «История заказов», «Недавно просмотренные», «Категория» и «Инвентарь» по отдельности, и, прежде чем вы это узнаете, вы выполняете 20 запросов, прежде чем сможете даже начать обслуживание страницы. Это просто разрушает производительность.

    Некоторые фреймворки - и я думаю здесь в основном о NHibernate - невероятно умны в этом отношении и позволяют вам использовать то, что называется фьючерсами, которые объединяют целые запросы и пытаются выполнить их все сразу, в последнюю возможную минуту. AFAIK, ты сам по себе, если хочешь сделать это с помощью любой из технологий Microsoft; Вы должны встроить это в логику своего приложения.

  5. Индексирование, предикаты и прогнозы

    По крайней мере, 50% разработчиков, с которыми я общаюсь, и даже некоторые администраторы баз данных имеют проблемы с концепцией покрытия индексов. Они думают: «Ну, Customer.Nameстолбец проиндексирован, поэтому каждый поиск, который я делаю по имени, должен быть быстрым». За исключением того, что это не работает таким образом, если Nameиндекс не охватывает конкретный столбец, который вы ищете. В SQL Server это делается с INCLUDEпомощью CREATE INDEXоператора.

    Если вы наивно используете SELECT *везде - и это более или менее то, что будет делать каждый ORM, если вы явно не укажете иное с помощью проекции - тогда СУБД вполне может решить полностью игнорировать ваши индексы, поскольку они содержат непокрытые столбцы. Проекция означает, что, например, вместо этого:

    from c in db.Customers where c.Name == "John Doe" select c
    

    Вы делаете это вместо этого:

    from c in db.Customers where c.Name == "John Doe"
    select new { c.Id, c.Name }
    

    И это будет, для большинства современных ORMs, поручить это только пойти и запросить Idи Nameстолбцы , которые предположительно охватываемые индексом (но не Email, LastActivityDateили любые другие столбцы случились придерживаться там).

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

    from c in db.Customers where c.Name.Contains("Doe")
    

    ... выглядит почти идентично нашему предыдущему запросу, но на самом деле приведет к полному сканированию таблицы или индекса, потому что оно переводится в LIKE '%Doe%'. Аналогично, другой запрос, который выглядит подозрительно простым:

    from c in db.Customers where (maxDate == null) || (c.BirthDate >= maxDate)
    

    Предполагая, что у вас есть индекс BirthDate, у этого предиката есть хороший шанс сделать его полностью бесполезным. Наш гипотетический программист, очевидно, пытался создать своего рода динамический запрос («фильтровать только дату рождения, если этот параметр был указан»), но это неправильный способ сделать это. Вместо этого написано так:

    from c in db.Customers where c.BirthDate >= (maxDate ?? DateTime.MinValue)
    

    ... теперь движок БД знает, как это настроить и выполнить поиск по индексу. Одно незначительное, казалось бы, незначительное изменение в выражении запроса может существенно повлиять на производительность.

    К сожалению, LINQ в целом делает слишком легким написание плохих запросов, подобных этому, потому что иногда провайдеры могут угадать, что вы пытались сделать, и оптимизировать запрос, а иногда нет. Таким образом, вы получите разочаровывающе противоречивые результаты, которые были бы ослепительно очевидными (для опытного администратора БД, во всяком случае), если бы вы только что написали простой старый SQL.

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

  6. Транзакции и блокировка

    Нужно ли отображать данные с точностью до миллисекунды? Возможно - это зависит - но, вероятно, нет. К сожалению, Entity Framework не дает вамnolock , вы можете использовать только READ UNCOMMITTEDна уровне транзакции (не на уровне таблицы). На самом деле ни один из ОРМ не является особенно надежным по этому поводу; если вы хотите выполнять грязное чтение, вам нужно перейти на уровень SQL и написать специальные запросы или хранимые процедуры. Итак, все сводится к тому, насколько легко вам сделать это в рамках.

    Entity Framework прошел большой путь в этом отношении - версия 1 EF (в .NET 3.5) была ужасна, сделав невероятно трудным прорвать абстракцию «сущностей», но теперь у вас есть ExecuteStoreQuery и Translate , так что это действительно не плохо. Подружитесь с этими парнями, потому что вы будете их часто использовать.

    Существует также проблема блокировок записи и взаимоблокировок, а также общая практика удержания блокировок в базе данных как можно меньше времени. В этом отношении большинство ORM (включая Entity Framework) на самом деле имеют тенденцию быть лучше, чем необработанный SQL, поскольку они инкапсулируют шаблон единицы работы , который в EF - SaveChanges . Другими словами, вы можете «вставлять», «обновлять» или «удалять» сущности в свое душевное содержание, когда захотите, и быть уверенными в том, что никакие изменения на самом деле не будут переданы в базу данных, пока вы не передадите единицу работы.

    Обратите внимание, что UOW не является аналогом длительной транзакции. UOW все еще использует функции оптимистичного параллелизма ORM и отслеживает все изменения в памяти . Ни один оператор DML не генерируется до окончательной фиксации. Это позволяет максимально сократить время транзакции. Если вы создаете свое приложение, используя сырой SQL, довольно трудно добиться этого отложенного поведения.

    Что это конкретно означает для EF: Сделайте ваши единицы работы как можно более грубыми и не передавайте их до тех пор, пока вам это не понадобится. Сделайте это, и вы получите гораздо меньшую конкуренцию за блокировку, чем при использовании отдельных команд ADO.NET в случайное время.

В заключение:

EF полностью подходит для приложений с высоким трафиком / высокой производительностью, точно так же, как любая другая среда подходит для приложений с высоким трафиком / высокой производительностью. Важно то, как вы используете это. Вот быстрое сравнение наиболее популярных фреймворков и того, что они предлагают с точки зрения производительности (легенда: N = не поддерживается, P = частично, Y = да / поддерживается):

                                | L2S | EF1 | EF4 | NH3 | ADO
                                +-----+-----+-----+-----+-----
Lazy Loading (entities)         |  N  |  N  |  N  |  Y  |  N
Lazy Loading (relationships)    |  Y  |  Y  |  Y  |  Y  |  N
Eager Loading (global)          |  N  |  N  |  N  |  Y  |  N
Eager Loading (per-session)     |  Y  |  N  |  N  |  Y  |  N
Eager Loading (per-query)       |  N  |  Y  |  Y  |  Y  |  Y
Level 1 (Identity) Cache        |  Y  |  Y  |  Y  |  Y  |  N
Level 2 (Query) Cache           |  N  |  N  |  P  |  Y  |  N
Compiled Queries                |  Y  |  P  |  Y  |  N  | N/A
Multi-Queries                   |  N  |  N  |  N  |  Y  |  Y
Multiple Result Sets            |  Y  |  N  |  P  |  Y  |  Y
Futures                         |  N  |  N  |  N  |  Y  |  N
Explicit Locking (per-table)    |  N  |  N  |  N  |  P  |  Y
Transaction Isolation Level     |  Y  |  Y  |  Y  |  Y  |  Y
Ad-Hoc Queries                  |  Y  |  P  |  Y  |  Y  |  Y
Stored Procedures               |  Y  |  P  |  Y  |  Y  |  Y
Unit of Work                    |  Y  |  Y  |  Y  |  Y  |  N

Как вы можете видеть, EF4 (текущая версия) выглядит не так уж плохо, но, вероятно, это не лучший вариант, если производительность является вашей главной задачей. NHibernate гораздо более зрелый в этой области, и даже Linq to SQL предоставляет некоторые повышающие производительность функции, которых EF еще не имеет. Необработанный ADO.NET часто будет работать быстрее для очень специфических сценариев доступа к данным, но, когда вы соберете все части воедино, он на самом деле не предлагает много важных преимуществ, которые вы получаете от различных сред.

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

Aaronaught
источник
38
Какой удивительный и исчерпывающий ответ!
2
+1 (больше, если смогу) - один из лучших ответов, которые я когда-либо видел здесь, и я кое-что узнал - спасибо, что поделился этим!
BrokenGlass
1
Это отличный ответ, даже если я не согласен со всем упомянутым. Таблица сравнения ORM не всегда верна. Что такое сущности ленивой загрузки? Вы имеете в виду ленивые загруженные столбцы? Это поддерживается в L2S. Как вы думаете, почему NH не поддерживает скомпилированные запросы? Я думаю, что именованные HQL-запросы могут быть предварительно скомпилированы. EF4 не поддерживает несколько наборов результатов.
Ладислав Мрнка
11
Я должен категорически не согласиться с безоговорочным утверждением «EF вполне подходит для приложений с высоким трафиком / высокой производительностью», мы неоднократно видели, что это не так. Конечно, возможно, мы не согласны с тем, что означает «высокая производительность», но, например, оптимизация веб-страниц до 500 мс и неоправданно более 400 мс, потраченных внутри фреймворка (и только 10 мс, фактически достигающих SQL), не подходит для некоторых ситуаций, это совершенно неприемлемо для нашей команды разработчиков.
Ник Крейвер
1
Простая заметка о фьючерсах в EF. Они официально не предоставляются командой MS EF, но могут быть реализованы с помощью сторонних проектов, которые определяют будущие <> расширения для IQueryable <>. Например, EntityFramework.Extended LoreSoft, доступный в NuGet. Мои персональные тесты в производственных приложениях показывают прирост производительности до 10 раз при упаковке десятков независимых запросов (все запросы могут выполняться параллельно, никому не требуется результат предыдущего) в одном пакете с использованием Future. Также AsNoTracking () значительно повышает производительность, когда просто читаешь много записей, а не обновляешься позже.
Дэвид Оливан Убието
38

Изменить: На основе @Aaronaught отличный ответ, я добавляю несколько пунктов, нацеленных на производительность с EF. Эти новые точки имеют префикс Edit.


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

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

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

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

  • Тщательно пересмотрите доступ к данным с помощью профилировщика SQL и просмотрите ваши запросы LINQ, если они правильно используют Linq-to-entity вместо Linq-to-objects
  • Очень осторожно используйте передовые функции оптимизации EF, такие как MergeOption.NoTracking
  • Используйте ESQL в некоторых случаях
  • Предварительно скомпилированные запросы, которые выполняются часто
  • Подумайте об использовании оболочки EF Caching для получения функции, подобной кэшу второго уровня, для некоторых запросов.
  • Используйте представления SQL или настраиваемые сопоставленные запросы SQL (требуется ручное ведение файла EDMX) в некоторых сценариях для часто используемых проекций или агрегаций, которые требуют повышения производительности
  • Используйте собственный SQL и хранимые процедуры для некоторых запросов, которые не обеспечивают достаточную производительность при определении в Linq или ESQL
  • Редактировать: осторожно использовать запросы - каждый запрос делает отдельную поездку в базу данных. EFv4 не имеет пакетной обработки запросов, потому что он не может использовать несколько наборов результатов на одну выполненную команду базы данных. EFv4.5 будет поддерживать несколько наборов результатов для сопоставленных хранимых процедур.
  • Изменить: Тщательно работать с изменениями данных. Опять же, EF полностью не хватает командного пакетирования . Таким образом, в ADO.NET вы можете использовать один SqlCommandфайл, содержащий несколько вставок, обновлений или удалений, но с EF каждая такая команда будет выполняться в отдельном направлении туда и обратно в базу данных.
  • Редактировать: Тщательно работать с идентификационной картой / кешем идентификации. EF имеет специальный метод ( GetByKeyв API-интерфейсе ObjectContext или Findв API-интерфейсе DbContext) для предварительного запроса в кэш. Если вы используете Linq-to-entity или ESQL, он создаст обратную передачу в базу данных и после этого вернет существующий экземпляр из кэша.
  • Редактировать: осторожно использовать нетерпеливую загрузку. Это не всегда беспроигрышное решение, потому что оно дает один огромный набор данных . Как видите, здесь много дополнительной сложности, и в этом весь смысл. ORM упрощает картографирование и материализацию, но когда речь идет о производительности, это значительно усложняет задачу, и вам придется идти на компромиссы.

Я не уверен, что SO все еще использует L2S. Они разработали новый ORM с открытым исходным кодом под названием Dapper, и я думаю, что основным моментом этой разработки было повышение производительности.

Ладислав Мрнка
источник
Ладислав, это действительно полезный ответ. Я впервые слышу о Dapper (и, следовательно, обнаружил PetaPoco, Massive) - и это выглядит как интересная идея.
1
Кажется, теперь SO использует сочетание LINQ to SQL и Dapper: samsaffron.com/archive/2011/03/30/… Цитата: «Мы используем наш новый ORM [Dapper] для конкретной проблемы: сопоставления параметризованного SQL с бизнес-объектами Мы не используем его как полноценный ORM. Он не выполняет отношений и других наворотов. Это позволяет нам продолжать использовать LINQ-2-SQL, где производительность не имеет значения, и переносить весь наш встроенный SQL для использования нашего преобразователя, так как это быстрее и гибче. "
5
@ Слаума хорошо, это заявление от нескольких месяцев назад, в целом вся новая работа над SO выполняется в Dapper, например, новая таблица, которую я добавил сегодня, отсутствует даже в файле dbml.
Сэм Шафран
1
@Sam: Есть ли новое сообщение в блоге о текущей стратегии доступа к данным на SO? Было бы очень интересно! Даппер был расширен за это время? Насколько я понимаю, Dapper не является полной ORM, не поддерживает отношения - а как насчет обновлений, вставок, удалений, транзакций, отслеживания изменений и т. Д.