Entity Framework з великими системами - як розділити моделі?


50

Я працюю з базою даних SQL Server з 1000+ таблицями, ще декількома сотнями переглядів та кількома тисячами збережених процедур. Ми хочемо почати використовувати Entity Framework для наших нових проектів, і ми працюємо над нашою стратегією для цього. Те, про що я повісив, - це як краще розділити таблиці на різні моделі (EDMX або DbContext, якщо ми спочатку перейдемо до коду). Я можу придумати декілька стратегій прямо біля кажана:

  • Розділити за схемою
    У нас таблиці розбиті напевно на десяток схем. Ми могли зробити одну модель за схемою. Однак це не ідеально, тому що dbo все ще залишається дуже великим, з 500+ таблицями / переглядами. Ще одна проблема полягає в тому, що певним одиницям роботи в кінцевому підсумку доведеться робити транзакції, що охоплюють кілька моделей, що додає складності, хоча я припускаю, що EF робить це досить просто.
  • Розділити за наміром
    Замість того, щоб турбуватися про схеми, розділіть моделі за наміром. Таким чином, ми будемо мати різні моделі для кожної програми, проекту, модуля чи екрана, залежно від того, наскільки детально ми хочемо отримати. Проблема, яку я бачу з цим, полягає в тому, що існують певні таблиці, які неминуче повинні використовуватися у кожному випадку, наприклад, користувач або аудит-історія. Чи додаємо ми їх до кожної моделі (порушує DRY, я думаю), чи це в окремій моделі, яка використовується кожним проектом?
  • Не розбивайтесь взагалі - одна гігантська модель
    Це, очевидно, просто з точки зору розвитку, але з мого дослідження та моєї інтуїції це здається, що це могло б бути страшним, як під час розробки, так і під час компіляції та, можливо, в процесі роботи.

Яка найкраща практика використання EF щодо такої великої бази даних? Зокрема, які стратегії використовують люди при розробці моделей щодо цього обсягу об'єктів БД? Чи є варіанти, що я не думаю, що це працює краще, ніж те, що я маю вище?

Також це проблема в інших ОРМ, таких як NHibernate? Якщо так, вони придумали якісь кращі рішення, ніж EF?


"потрібно робити транзакції, що охоплюють кілька моделей, що додає складності" Тут лише зауважте, що вам потрібно ввімкнути Координатор розподілених транзакцій Microsoft. Після того, як у вас це буде запущено, виконувати те, про що ви говорите, повинно бути просто.
Тярт

@Tjaart спасибі Я раніше використовував MS DTC, і хоча він досить простий, він додає складності поза простим DBx txn, тому я хочу уникати цього, коли це можливо.
RationalGeek

2
Через 4 роки, що ви вирішили і що б зараз рекомендували?
Рорі

Відповіді:


31

Особисто я намагався скласти одну величезну схему для всіх моїх сутностей на досить складному, але невеликому проекті (~ 300 таблиць). У нас була надзвичайно нормалізована база даних (нормалізація 5-ї форми (я кажу, що це вільно)) із безліччю взаємозв'язків "багато-багато" та надзвичайним забезпеченням референтної цілісності.

Ми також використовували стратегію "одиночний екземпляр на запит", яка, я не впевнений, також допомогла.

Коли ви робите прості, досить плоскі "чітко визначені" списки, пошук і зберігає продуктивність, як правило, прийнятні. Але коли ми почали заглиблюватись у глибокі стосунки, виступ здавалося, що він сприйняв різкі затримки. Порівняно із збереженим процесором у цьому випадку, порівняння (звичайно) не було. Я впевнений, що ми могли переробити базу коду тут і там, щоб покращити продуктивність, однак, у цьому випадку нам просто потрібно було підвищити продуктивність без аналізу через обмеження в часі, і ми повернулися до збереженого процесору (все-таки це відображено через EF, оскільки EF дав сильно набрані результати), нам це було потрібно лише як відступ у кількох районах. Коли нам довелося об’їхати всю базу даних, щоб створити колекцію (використовуючи .include () нерівномірно), продуктивність була помітно принижуючою, але, можливо, ми запитували занадто багато.

Отже, виходячи з мого досвіду, я б рекомендував створити окремий .edmx за наміром. Генеруйте лише те, що ви будете використовувати, виходячи з обсягу цієї потреби. У вас можуть бути декілька менших масштабних файлів .edmx для цільових завдань, а потім деякі великі, де вам потрібно пройти складні зв’язки для побудови об’єктів. Я не впевнений, де це чарівне місце, але я впевнений, що є одне ... lol ...

Чесно кажучи, окрім кількох підводних каменів, які ми начебто побачили (складний проїзд), величезна. Але вам доведеться стежити за магією "виправлення", яку робить контекст поза сценою, якщо ви не відключите її прямо. Окрім того, щоб синхронізувати .edmx під час внесення змін у базу даних. Іноді було легше стерти всю поверхню та заново створити об'єкти, на що пішло 3 хвилини, тому це не було великою справою.

Це все було з EntityFramework 4.1. Мені б дуже цікаво почути про ваш кінцевий вибір та досвід.

А щодо вашого питання щодо nHibernate, на мою думку, це питання про глистів, на мою думку, ви отримаєте гавкіт з обох боків огорожі ... Я чую, що багато людей б'ють EF заради того, щоб бити, не працюючи через виклики та розуміння нюансів, властивих самому EF. І хоча я ніколи не використовував nhibernate у виробництві, як правило, якщо вам доведеться вручну та явно створювати такі речі, як відображення, ви все-таки отримаєте більш обмежений контроль, якщо ви можна перетягувати, генерувати та запускати CRUD'інг та запити за допомогою LINQ, я міг би дати лайно про деталізацію.

Я сподіваюся, що це допомагає.


1
FYI - Існує програма для картографування NHibernate, яка робить ці відображення ДУЖЕ легкими та автоматизованими.
подарунки

@ganders - Чи має інтерфейс користувача і як це інтеграція IDE? Я припускаю, що ви вказали його на джерело даних, і воно поважає референтну цілісність та обхід об'єктів і створює об'єкти відображення?
ханзоло

1
Так, це так (GUI). У мене до цього часу виникали нульові проблеми. Використовували його на 4 або 5 різних проектах / веб-сайтах. Примітка: я використовую його з Fluent NHibernate, який робить відображення в коді c #, а не у файлах config / xml. Ось посилання: nmg.codeplex.com
гуси

13

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

Отже, у вас є велика база даних, і ви хочете використовувати її з ORM / EF. Я б пішов з другим вибором. Ось моє просте пояснення, чому:

  • Картографування додає складності. Немає необхідності додавати складності суб'єктам, які вам ніколи не потрібні, але не роблять деталізацію занадто низькою. Маючи окремий набір карт на екран, вам також не допоможе.
  • Ви хочете досягти одиниці роботи. Ви повинні мати можливість вказати, який модуль таблиць потрібен у більшості випадків (необхідний не у всіх випадках). Якщо ви помістите ці таблиці в єдиний набір відображення, ви зможете обробляти читання та зміну даних одним екземпляром контексту - саме це має бути вашою кінцевою ціллю.
  • Я не впевнений, що саме ви маєте на увазі під моделлю, але навіть за допомогою різних наборів відображень ви можете ділити класи між наборами відображення, використовуючи ті самі типи сутності. Отже, якщо ви використовуєте таблицю User у двох модулях, вам не потрібні два класу користувача, щоб представляти однакові. Ви все ще можете використовувати одну таблицю, і в разі зіставлення коду (він же код-перший) ви навіть можете один раз визначити відображення і завантажити його в кілька наборів відображення, щоб принцип DRY не порушувався, але підхід для першого коду має більше обмежень, якщо мова йде про для перегляду та збережених процедур. EDMX робить це складніше. Ви все ще можете повторно використовувати класи, але повторне використання карти неможливо.
  • Що щодо запитів між модулями? Ці запити можуть траплятися, але якщо чесно, не все повинно вирішуватися EF. Ви можете скористатися EF для звичайних випадків для спрощення регулярного доступу до даних, але якщо вам десь потрібен спеціальний запит, який з'єднує таблиці, що належать до 5 різних модулів, ви можете просто виконати його безпосередньо або зафіксувати в збереженій процедурі. 100% заміна нативного доступу до даних може бути важкою, складною та контрпродуктивною.
  • Останній пункт просто практичний: я не вірю, що інструменти VS готові працювати з таким великим набором об'єктів - навіть не в дизайнері, навіть не з інструментом імпорту. Раніше я працював над дуже великою базою даних з традиційним доступом до даних та проектом SQL Database у VS2008 - досвід роботи зі складним проектом був дуже поганим. Ви повинні тримати низьку кількість використаних таблиць - обмеження для дизайнера має бути десь між 100-200, але навіть 100 таблиць, оброблених одним контекстом (набір картографування), звучать як занадто велика відповідальність за один клас (припустимо, у вас буде 100 властивостей набору експоновані в контексті - це не схоже на хороший дизайн).

4

Я б сказав, що ви не можете вирішити подібне питання з технічної точки зору. Я рекомендую вам будувати свою архітектуру на основі випадків використання (розповіді користувачів тощо). Спочатку знайдіть об’єкти свого бізнесу. Об'єкт суб'єкта господарювання не є за замовчуванням бізнес-об'єктом. Зазвичай у вас буде бізнес-об'єкт перед об'єктами сутності. Тоді ви можете поступово вирішувати, що вам дійсно потрібно, виходячи з вимог користувача.

"Хороший архітектор максимально збільшує кількість не прийнятих рішень". Роберт К. Мартін

http://cleancoder.posterous.com/architecture-deference


3

Я використовую гібридний підхід - матеріали OLTP обробляють EF, тоді як складні операції, такі як пакетні вставки, масові оновлення, запити звітів тощо, обробляють Stored Procs. Це також полегшує шлях міграції, якщо ви не здійснюєте повного переписування шару даних відразу.


Це здається гарною стратегією, але насправді не вирішується питання про те, як розділити сутності на різні моделі EF. У вас є всі сутності в одній моделі або ви поділяєтесь і підкоряєте якимось чином?
RationalGeek

1
Якщо продуктивність OLTP достатня для підходу в повній моделі, перейдіть до цього. Ви завжди можете розірвати це пізніше, якщо вам доведеться, але найшвидший і найспритніший спосіб - це завантажувати всю справу. Можливо, вам ніколи не знадобиться підвищення продуктивності, яке ви отримуєте, розбиваючи його, тож ви витрачаєте час і не ускладнюєте свою систему. Тоді виникає питання, до якої моделі ви б приклеїли нову таблицю / сутність, коли ви вирішите розширити. І що відбувається, коли потрібно запустити оновлення для кількох моделей. Збережіть собі головний біль, якщо у вас справді немає альтернативи.
Нік

Забув зазначити, що ви завжди можете налаштувати свою ефективність під час доступу до своїх даних. Подивіться на ліниві / нетерплячі варіанти завантаження та які дочірні сутності ви вводите. Я не бачу причини, щоб повна модель поводилася гірше, ніж менша, якщо ви не завантажуєте масивні дерева об'єктів.
Нік

я б сказав, що масивні дерева об'єктів і нормалізована структура даних йдуть на руку при роботі з великими схемами
hanzolo

Ви керуєте тим, наскільки мало або скільки ви хочете наситити графік об'єкта.
Нік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.