NHibernate и несколько баз данных базы данных - архитектура - PullRequest
4 голосов
/ 29 апреля 2009

У меня есть проект, который должен работать на разных (как минимум 2) серверных базах данных, чтобы пользователи могли выбирать (в настоящее время между MSSQL и SQLite). Я только начал изучать NHibernate, следуя инструкции на nhibernate.info .

Теперь моя текущая архитектура выглядит так:

MyProject.DAL

Содержит NewsItem и INewsItemRepository . NewsItem - это POCO, по сути, просто int Id и строковый заголовок.

INewsItemRepository - это интерфейс, который включает в себя функциональность CRUD.

MyProject.Plugins.DAL.MSSQL

Этот класс реализует бэкэнд. Включает hibernate.cfg.xml , NewsItem.hbm.xml и NewsItemRepository .

В cfg содержатся Driver и ConnectionString, hbm - это привязка, специфичная для SQL-сервера, а NewsItemRepository реализует INewsItemRepository.

Если я хочу добавить MyProject.Plugins.DAL.SQLite, мне придется продублировать все это, что логично. Тем не менее, мне интересно, если это правильный подход? Я чувствую, что я излишне дублирую вещи. Я имею в виду: мне нужно убедиться, что отображение относится к базе данных, и что я обновляю все мои плагины, если база данных изменяется. Но эта архитектура все еще кажется чем-то ... раздутой.

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

Редактировать: Одной из проблем здесь является обработка sql-типов. Например, строки отображаются как nvarchar (255) по умолчанию, и если мне нужен ntext в MSSQL, мне придется использовать синтаксис в общем проекте DAL, а затем теги .hbm в каждой серверной сборке, содержащей столбцы?

Ответы [ 3 ]

4 голосов
/ 29 апреля 2009

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

Одним из основных преимуществ использования ORM, такого как NHibernate, является то, что они отделяют ваш код от вашей персистентной архитектуры. Мне кажется, что отображение NewsItem (например) несколько раз, например, не нужно. Разве модель данных не может быть одинаковой независимо от серверной части? Возможно, вы могли бы привести пример, где они могут отличаться.

Во-вторых, я бы, вероятно, не реализовал заново репозиторий NewsItem. Независимо от базы данных, хранилище использует NHibernate, основной целью которого является абстрагирование базы данных. Все функции CRUD, обрабатываемые репозиторием, будут такими же в MSSQL, как и в SQLite (если на самом деле нет разницы в модели данных).

Если ваша модель базы данных одинакова на обоих серверах, теоретически вам нужно всего лишь изменить строку подключения, чтобы изменить используемую базу данных. Способ, которым я реализовал DAL прежде, состоит в том, чтобы предоставить интерфейсы, как вы сделали, а затем иметь подпространство имен для реализаций, одно (ну, на данный момент, единственное на данный момент;), являющееся NHibernate. Репозитории и соавт. приобретаются путем внедрения зависимости. Ядро DI также обрабатывает фабрики сессий, поэтому легко ориентироваться на разные базы данных для разных разделов кода.

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

EDIT:

Я понимаю, что вы имеете в виду под типом sql. Однако это проблема, только если вы генерируете схему для своей базы данных из NHibernate. При сопоставлении свойств вам не нужно , чтобы использовать <column>, а тип, указанный в <property>, является типом NHibernate. Тип StringClob будет правильно обрабатывать поля NTEXT.

Если вы генерируете свою схему из сопоставлений NHibernate и NHibernate не достаточно умен, чтобы отбросить sql-type = "NTEXT" для SQLite (я надеюсь, что это есть, но я никогда не использовал инструмент генерации схемы), думаю, я бы добавил шаг сборки для очистки схемы SQLite. Конечно, теперь вы добавляете сложность в свой процесс, так что решать вам. Тем не менее, я бы предпочел, чтобы мой код и отображения были как можно более простыми и чистыми и сохраняли сложность только там, где это необходимо (подробности механизма базы данных). Мне кажется, что хранение двух отдельных файлов сопоставления - это рецепт отсутствующего сопоставления свойств, и пользователи забывают о том, почему они не могут вставить свою DOB при использовании SQLite;)

EDIT2 (относительно использования DI с NH):

Это немного субъективно, так как я уверен, что есть много способов использовать DI с NHibernate. Я имел большой успех, используя DI с Fluent NHibernate и Ninject , структурой DI, которая также использует "свободный" DSL. Fluent NHibernate (FNH) предоставляет интерфейс IPersistenceConfigurer, который используется для создания строки подключения к вашей базе данных (он также предоставляет несколько диалектов на выбор). Таким образом, этот сервис IPersistenceConfigurer легко связать с провайдером через инфраструктуру DI. Вы можете сделать то же самое для ISessionFactory, чтобы получить полностью D-впрыскиваемый завод. Поскольку Ninject работает с атрибутами, мой конструктор хранилища может выглядеть так:

[Inject, CRM]
public MyRepository(ISessionFactory sessionFactory)

Что добавит фабрику для базы данных CRM. Мне нравиться :)

1 голос
/ 29 апреля 2009

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

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

1 голос
/ 29 апреля 2009

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

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