Чи підходить Entity Framework для веб-сайтів із високим трафіком?


176

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

На мій погляд, EF - це життєздатне рішення для більшості менших веб-сайтів чи інтрамереж, але воно не може легко масштабувати щось на зразок популярного веб-сайту спільноти (я знаю, що ТАК використовує LINQ для SQL, але .. Я хотів би більше прикладів / доказів. ..)

Тепер я стою на перехресті або вибору чистого підходу ADO.NET, або EF4. Чи вважаєте ви, що поліпшення продуктивності розробників за допомогою EF варто втратити продуктивність та детальний доступ ADO.NET (із збереженими процедурами)? Будь-які серйозні проблеми, з якими може зіткнутися веб-сайт із високим трафіком, це він використовував EF?

Спасибі заздалегідь.


1
Ви не розумієте масштабування. Масштабування означає отримання 10-кратної пропускної здатності, коли ви додаєте 10-кратну ємність. Чому EF перешкоджає цьому? Це додає постійний накладний навантаження на будь-яку завантаженість бази даних.
usr

Відповіді:


152

Це трохи залежить від того, скільки абстракції вам потрібно . Все - компроміс; наприклад, EF і NHibernate ввести велику гнучкість для представлення даних в цікавих і екзотичних моделях - але в результаті вони роблять додати накладні витрати. Помітні накладні.

Якщо вам не потрібно мати можливість перемикатися між постачальниками баз даних і різними макетами клієнтських таблиць, і якщо ваші дані в основному читаються , і якщо вам не потрібно мати змогу використовувати ту саму модель у EF, SSRS , Послуги даних даних ADO.NET тощо - тоді, якщо ви хочете, щоб абсолютна продуктивність була вашим ключовим показником, ви могли б зробити набагато гірше, ніж дивитися на Dapper . У наших тестах, що базуються як на LINQ-SQL, так і на EF, ми виявляємо, що EF значно повільніше з точки зору продуктивності зчитування в сировині, імовірно, завдяки шарам абстракції (між моделлю зберігання тощо) та матеріалізації.

У нас в SO ми нав'язливо нав'язливі щодо сильної продуктивності, і ми раді прийняти хіт розвитку, щоб втратити деяку абстракцію, щоб отримати швидкість. Таким чином, наш основний інструмент для запитів до бази даних - dapper . Це навіть дозволяє використовувати нашу раніше існуючу модель LINQ-SQL, але просто: вона накопичується швидше. У тестах на ефективність це фактично та сама продуктивність, що і введення всіх код ADO.NET (параметрів, зчитувачів даних тощо) вручну, але без ризику неправильної назви стовпця. Це, однак, на базі SQL (хоча із задоволенням використовують SPROC, якщо це обрана вами отрута). Перевагою цього є те , що не існує НЕ додаткова обробка бере участь, але це система для тих , хто любить SQL. Я вважаю: не погана річ!

Наприклад, типовим запитом може бути:

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

що зручно, безпечно для ін'єкцій тощо - але без тонн goo-зчитувача даних. Зауважте, що, хоча він може обробляти як горизонтальні, так і вертикальні розділи для завантаження складних структур, він не підтримує ледачий навантаження (але: ми великі шанувальники дуже явного завантаження - менше сюрпризів).

Зауважте, у цій відповіді я не кажу, що EF не підходить для роботи з великими обсягами; просто: я знаю, що Dapper вирішує це.


25
+1 для Dapper. Використання складного ORM для моделей, що читаються, просто зайве. Підхід, який ми застосовуємо зараз, полягає у використанні ORM для нашої моделі домену (де модні речі ORM насправді корисні) та dapper для нашої моделі читання. Це робить дуже швидкими додатки.

2
@Marc, дякую за чудову відповідь - я нарешті можу прийняти своє рішення з упевненістю! Однозначно згодом детальніше розберемося в Dapper. Дуже подобається, як це лише один файл :)

3
Я записав власну ORM. Її повільно. Я подивився на Dapper і сподобалось. Зараз я використовую Dapper для всіх своїх читань та власний ORM для вставок (який підтримує FK, транзакції та всі хороші речі). Це найпростіший читабельний код, який я коли-небудь писав.

2
@ acidzombie24 dapper підтримує транзакції, і частина вкладки dapper (не частина нульового розгортання) отримує параметри вставок тощо. Просто згадую про повноту. Я радий, що Dapper був корисний.
Марк Гравелл

1
@anyname Я ніколи не робив відеокурс на будь-яку тему; є кілька відео там, але не від мене. Я схильний бути людиною з письмовим словом
Марк Гравелл

217

Питання "який ORM я повинен використовувати" насправді орієнтований на вершину величезного айсберга, коли мова йде про загальну стратегію доступу до даних та оптимізацію продуктивності в масштабному застосуванні.

Усі наступні речі ( приблизно за важливістю) впливатимуть на пропускну здатність, і всі вони обробляються (іноді різними способами) більшістю основних каркасів ORM:

  1. Дизайн та обслуговування баз даних

    Це, з великим запасом, єдиний найважливіший визначальний коефіцієнт пропускної здатності керованого даними програми або веб-сайту, який часто повністю ігнорується програмістами.

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

    Якщо ви не скористаєтесь функціями, які надає вам база даних, наприклад стиснення сторінок, FILESTREAMзберігання (для двійкових даних), SPARSEстовпці, hierarchyidієрархії тощо (усі приклади SQL Server), ви не побачите ніде поблизу вистава, яку ви могли бачити.

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

  2. Ігр проти ледачого завантаження

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

    Це не є хорошою чи поганою річчю, скоріше залежить від того, що насправді буде зроблено з даними та наскільки ви знаєте наперед. Іноді ледачий навантаження - це абсолютно правильна річ. Наприклад, NHibernate може вирішити взагалі нічого не запитувати і просто генерувати проксі для певного ідентифікатора. Якщо все, що вам коли-небудь потрібно, - це саме ідентифікатор, чому він повинен просити більше? З іншого боку, якщо ви намагаєтеся надрукувати дерево кожного окремого елемента в 3-х рівневій ієрархії, ліниве завантаження стає операцією O (N²), що вкрай погано для продуктивності.

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

  3. Кешування

    Усі основні ORM підтримують кеш першого рівня, "кеш ідентичності" AKA, що означає, що якщо ви двічі запитаєте одне і те ж об'єкт за його ідентифікатором, воно не потребує другого зворотного шляху, а також (якщо ви правильно створили свою базу даних ) дає можливість використовувати оптимістичну одночасність.

    Кеш L1 досить непрозорий у L2S та EF, вам належить вірити, що він працює. NHibernate про це явніше ( Get/ Loadпроти 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% розмов, з якими я розмовляю, і навіть деякі DBA, здається, мають проблеми з концепцією покриття індексів. Вони думають: "ну 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 в цілому робить занадто легко писати такі погані запити, тому що іноді постачальники можуть вгадати, що ви намагалися зробити, та оптимізувати запит, а іноді вони не так. Таким чином, ви закінчуєте розчаровуючи непослідовні результати, які були б сліпуче очевидними (як би це не було для досвідченого DBA), якби ви щойно написали звичайний старий SQL.

    В основному все зводиться до того, що вам справді слід уважно стежити як за згенерованим SQL, так і за планами виконання, які вони ведуть, і якщо ви не отримуєте очікуваних результатів, не бійтеся обійти Рівень ORM час від часу і вручну кодує SQL. Це стосується будь-яких ОРМ, а не лише 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 для SQL надає деякі функції для підвищення продуктивності, яких EF досі не має. Сирий ADO.NET часто буде швидше для дуже конкретних сценаріїв доступу до даних, але, коли ви складете всі частини разом, це дійсно не пропонує багато важливих переваг, які ви отримуєте від різних рамок.

І лише для того, щоб повністю переконатися, що я звучу як непрацюючий запис, нічого з цього не має значення, якщо ви не розробляєте належним чином свою базу даних, програми та стратегії доступу до даних. Усі елементи, наведені в діаграмі, наведені вище, - для підвищення продуктивності поза базовою лінією; більшу частину часу саме основна лінія - це те, що потребує найбільшого вдосконалення.


38
Яка дивовижна і всебічна відповідь!

2
+1 (більше, якщо я міг) - одна з найкращих відповідей, яку я бачив за деякий час, і я дізнався щось або дві - дякую, що поділився цим!
BrokenGlass

1
Це чудова відповідь, навіть я не згоден із усім згаданим. Таблиця, що порівнює ORM, не завжди є правильною. Що таке ліниве навантаження? Ви маєте на увазі ледачі завантажені колонки? Це підтримується в L2S. Чому, на вашу думку, NH не підтримує складені запити? Я думаю, що назви HQL-запитів можна попередньо скласти. EF4 не підтримує кілька наборів результатів.
Ладислав Мрнка

11
Я мушу категорично не погоджуватися з некваліфікованим твердженням "EF є повністю нормальним для високошвидкісних / високопродуктивних додатків", ми неодноразово бачили, що це не так. Зрозуміло, ми можемо не погоджуватися з приводу того, що означає "висока продуктивність", але, наприклад, оптимізація веб-сторінок до 500 мс та 400 мс + від того, що витрачено непомітно всередині рамки (і лише 10 мс насправді вражає SQL), не "добре" для деяких ситуацій, це абсолютно неприйнятно для нашої команди розробників.
Нік Крейвер

1
Проста примітка про ф'ючерси в EF. Вони офіційно не надаються командою MS EF, але вони можуть бути досягнуті за допомогою сторонніх проектів, які визначають розширення майбутнього <> IQueryable <>. Наприклад, EntityFramework.Extended by LoreSoft, доступний в NuGet. Мої особисті тести у виробничих додатках показують підвищення продуктивності до 10 разів при упаковці десятків незалежних запитів (усі запити можна виконувати паралельно, нікому не потрібен результат попереднього) в одній партії за допомогою Future. Також AsNoTracking () значно покращує продуктивність при просто читанні безлічі записів, не пізнішого оновлення.
Девід Оліван Убіето

38

Редагувати: На основі чудової відповіді @Aaronaught я додаю кілька балів, орієнтованих на ефективність за допомогою EF. Ці нові пункти мають префікс "Правка".


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

Відповіді на ваше запитання немає, оскільки це завжди залежить від вимог щодо застосування та складності запитів. Правда полягає в тому, що продуктивність розробників з EF приховує складність, за якою в багатьох випадках призводить до неправильного використання EF та жахливих показників. Ідея про те, що ви можете відкрити абстрагований інтерфейс високого рівня для доступу до даних, і він плавно працює у всіх випадках, не працює. Навіть з ORM ви повинні знати, що відбувається за абстракцією та як правильно ним користуватися.

Якщо у вас немає попереднього досвіду роботи з EF, ви зіштовхнетеся з безліччю проблем при роботі з ефективністю. Ви можете зробити набагато більше помилок під час роботи з EF порівняно з ADO.NET. Крім того, в EF є багато додаткової обробки, тому EF завжди буде значно повільніше, ніж нативний ADO.NET - це те, що можна виміряти простим доказом застосування концепції.

Якщо ви хочете отримати найкращу ефективність від EF, вам, швидше за все, доведеться:

  • Дуже ретельно перегляньте свій доступ до даних за допомогою SQL-профілера та перегляньте ваші LINQ-запити, чи правильно вони використовують Linq-to-subjekt замість Linq-до об'єктів
  • Дуже обережно використовувати розширені функції оптимізації 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-subjekti або ESQL, він створить зворотну пряму до бази даних, після чого поверне наявний екземпляр з кеша.
  • Редагувати: обережно використовуйте прагнення до завантаження. Це не завжди безпрограшне рішення, оскільки воно виробляє один величезний набір даних . Як бачите, це багато додаткової складності, і в цьому вся суть. ORM спрощує картографування та матеріалізацію, але якщо мати справу з продуктивністю, це зробить її набагато складнішою, і вам доведеться робити компроміси.

Я не впевнений, чи SO все ще використовує L2S. Вони розробили нову ORM з відкритим кодом під назвою Dapper, і я думаю, що головним моментом цієї розробки було підвищення продуктивності.


Ладіслав, це справді корисна відповідь. Це перший раз, коли я чую про Dapper (і, отже, виявив PetaPoco, Massive) - і це виглядає як цікава ідея.

1
Так, здається, зараз використовується суміш LINQ для SQL і Dapper: samsaffron.com/archive/2011/03/30/… Цитата: "Ми використовуємо наш новий ORM [Dapper] для конкретної проблеми: відображення параметризованого SQL для бізнес-об'єктів . Ми не використовуємо його як повноцінний ORM. Він не робить стосунків та інших дзвінків. Це дозволяє нам продовжувати використовувати LINQ-2-SQL, коли продуктивність не має значення і переносимо весь наш вбудований SQL для використання нашого картографа, оскільки це швидше і гнучкіше ".

5
@Slauma добре, це твердження від місяців тому, взагалі вся нова робота над SO виконується в Dapper, наприклад, нова таблиця, яку я сьогодні додав, навіть не є у файлі dbml.
Сам Шафран

1
@Sam: Чи є нова публікація в блозі про поточну стратегію доступу до даних про SO? Було б дуже цікаво! Чи був тим часом Dapper продовжений? Я розумів, що Dapper не є повноцінним органом управління, не підтримує стосунків - а що стосується оновлень, вставок, видалень, транзакцій, відстеження змін тощо.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.