Entity Framework Code - первое сопоставление TpT в составном приложении - PullRequest
2 голосов
/ 05 февраля 2012

Я работаю над составным комплексным системным приложением, в которое разные компании могут добавлять разные модули, но есть только одна база данных. У меня есть общий репозиторий в моей среде, который не зависит от технологии (я имею в виду его базу поставщиков и на данный момент - результат)провайдер EF 4.1). У меня есть отдельный общий слой, который содержит объекты poco, и в каждом модуле также есть различные объекты для каждого модуля.Теперь проблема заключается в отображении сущностей. У меня нет доступа к моим сущностям из моего проекта провайдера EF, так как я не знаю будущих модулей!так как я могу отобразить мои сущности в общем подходе?Возможно ли это?

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

Редактировать: Во-первых, спасибо за ваш ответ, Ладислав.Но есть и дополнительная информация для вас.

Вы можете сделать требование, чтобы каждый модуль содержал классы отображения для каждой новой сущности, которую он использует.Когда вы запускаете приложение, вы просто используете отражение, чтобы получить все классы, производные от StructuralTypeConfiguration <> (включая как сущности, так и сложные типы), создать экземпляры этих типов и добавить их в коллекцию Configurations в DbModelBuilder (это можно сделать в OnModelCreating).

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

Редактировать:

Я должен ссылаться на EntityFramework.dll вкаждый модуль, который не подходит в этом случае.

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

==> , как я упоминал ранее, EF - не единственный мой DataProvider!У меня должен быть какой-то другой DP, такой как поставщик данных для DB4O и т. Д., Поэтому я не хочу ссылаться на зависимости каждого провайдера для каждого модуля ... поэтому мне нужно инкапсулировать EF в отдельную сборку

Если вы используете репозитории, каждый модуль должен даже содержать свои собственные репозитории для работы со своими собственными сущностями - универсального репозитория не существует.Универсальный репозиторий - это лишний ненужный слой, который только усложняет работу с ORM по вашему выбору.Чтобы было понятно - правильная реализация шаблона репозитория не является общей.Он специфичен и предоставляет функциональные возможности доступа к данным для единого объекта или совокупного корня.

==> Могу ли я попросить любую надежную ссылку?!Зачем мне добавлять один репозиторий на модуль, если только один репозиторий может выполнить все мои требования?что избыточно?По моему мнению, использование определенных или общих повторений является правильным в правильной ситуации. 90% моих модулей предъявляют те же требования к хранилищу, и все они должны иметь CRUD ...

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

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

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

==> Хорошая идея, но не подходит для моего случая;)

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

Вы когда-нибудь видели такие приложения, как Photoshop, Visual Studio или даже Приложения MS Office во время их запуска? Что вы думаете происходит, когда вы видите заставку? Приложение инициализируется - оно загружает и инициализирует свои функции и плагины. Четный сервер Для полного запуска приложения может потребоваться несколько минут. Вы строите модульное приложение (не составное), поэтому вы должны заплатить за это требование.

==> Да, я думаю, что видел некоторые из них! Если они загружают, например, все паллеты или боковые панели при запуске, они должны нанимать меня. Уважаемый Microsoft, если вы не знаете, что такое отложенная загрузка, я могу помочь вам улучшить вашу производительность:)

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

==> Я уже использую Prism и MEF для обработки модульности, но только для модулей, не для моих провайдеров ...

Звучит так, что EF не является хорошим решением для корпоративного композитного приложения, верно?

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

==> Модель или промежуточный слой отображения, который будет работать в каждом модуле, загружать и отображать сущности, если EF поддерживает (что не может, как я знаю). Мне нужно что-то вроде загрузчика для каждого провайдера для сопоставления лица:)

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

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

Должен ли я сначала переключиться на модель? !!

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

==> но я могу изменить модель и XML-файл EDMX во время выполнения, верно?!

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

==> спасибо за этот совет, хотя я знал его раньше, но, разумеется, я уделю ему больше внимания.

1 Ответ

2 голосов
/ 05 февраля 2012

Вы можете сделать требование, чтобы каждый модуль содержал классы отображения для каждой новой сущности, которую он использует.Когда вы запустите приложение, вы просто будете использовать отражение, чтобы получить все классы, производные от StructuralTypeConfiguration<> (включая как сущности, так и сложные типы), создать экземпляры этих типов и добавить их в коллекцию Configurations в DbModelBuilder (это можно сделать вOnModelCreating).

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

Редактировать:

У меня естьссылаться на EntityFramework.dll в каждом модуле, который не подходит в этом случае.

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

Если вы используете репозитории, каждый модуль должен даже содержать свои собственные репозитории для работы со своими собственными сущностями - универсальный репозиторий не существует.Универсальный репозиторий - это лишний ненужный слой, который только усложняет работу с ORM по вашему выбору.Чтобы было понятно - правильная реализация шаблона репозитория не является общей.Он специфичен и предоставляет функциональные возможности доступа к данным для единого объекта или совокупного корня.

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

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

При запуске я должен отражать каждый dll модуля, что означает многотяжелых dll, которые нужно отразить и ... есть ли какая-нибудь другая идея?

Вы когда-нибудь видели приложения, такие как Photoshop, Visual Studio или даже приложения MS Office, при запуске?Как вы думаете, что происходит, когда вы видите заставку?Приложение инициализируется - оно загружает и инициализирует его функции и плагины.Даже серверному приложению может потребоваться несколько минут для полного запуска.Вы создаете модульное приложение (не составное), поэтому вы должны заплатить за это требование.

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

Звучит так, что EF не является хорошим решением для корпоративного составного приложения, верно?

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

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

Стоит ли переходить на Model First? !!

Modelfirst (и EDMX в целом) действительно не подходит для ваших ожиданий, потому что в случае модели first каждому модулю понадобится собственный файл EDMX и собственный контекст.

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

Последнее редактирование, потому что это не дискуссионный форум:

EF не мой единственный DataProvider!У меня должен быть какой-то другой DP, такой как ...

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

Могу ли я попросить любую надежную ссылку ?!Зачем мне добавлять один репозиторий на модуль, если только один репозиторий может выполнить все мои требования?что избыточно?

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

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

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

Модель или промежуточный слой картографирования, который будет работать в каждом модуле загрузки и отображать объектыесли поддержка EF (что не может, как я знаю), мне нужно что-то вроде начальной загрузки для каждого провайдера для сопоставления сущностей

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

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

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

Но я могу изменить модель и XML-файл EDMX во время выполнения, верно?

Попробуйте.Подсказка: нет общедоступного API для работы с этим XML на низкоуровневой основе, и нет общедоступного API для изменения загруженной модели.Можно изменить EDMX перед загрузкой, но обычно это означает написание собственного анализатора и компоновщика xml для SSDL, MSL и CSDL.У вас будет один набор файлов сопоставления, обновленный всеми установленными модулями.Вам также нужно будет выполнить обратную операцию, чтобы удалить модуль и правильно удалить все функции из сопоставления.Любая ошибка может повредить ваше приложение, потому что отображение будет повреждено.Моя первоначальная идея с загруженными конфигурациями для отображения кода займет у вас менее одного дня.Сколько времени потребуется, чтобы построить это?

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

...