2010-04-16 10 views
9

Мой проект должен обрабатывать три базы данных, что означает три сеансовых фабрики. Дело в том, если я делаю что-то подобное с Fluent NHibernate:Fluent NHibernate + несколько баз данных

.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())) 

фабрика будет забрать все отображения, даже те, которые соответствуют другой базе данных

Я видел, что при использовании Автоотображения вас может сделать что-то вроде этого, и фильтр имен:

.Mappings(m => m.AutoMappings.Add(
    AutoMap 
     .AssemblyOf<Product>() 
     .Where(t => t.Namespace == "Storefront.Entities"))) 

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

Я бы предпочел избежать обоих, если это возможно. Благодарю.

+2

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

+0

Похоже, мне нужно поместить все классы entitiy в другой проект, а другой проект для второго db. – CallMeLaNN

ответ

5

Я реализовал именно это, используя (собственный) Атрибут на Fluent файла отображения продиктовать который DB Лицо принадлежит. У меня также есть понятие база данных по умолчанию, а файлы сопоставления без атрибута, как предполагается, находятся в БД по умолчанию (он может сократить количество классов, которые необходимо украсить). Затем у меня есть код инициализации, который создает фабрику сеансов для каждой базы данных и для каждого использует отражение для поиска всех классов ClassMap, анализирует атрибут, чтобы определить, к какому БД он принадлежит, и соответственно регистрирует каждую ClassMap.

Отображение файла Пример:

[FluentNHibernateDatabase("MySecurityDatabase")] 
    public class SystemUserMap : ClassMap<SystemUser> 
    { 
    public SystemUserMap() 
    { 
     Id(x => x.SystemUserId); 
     Map(x => x.LoginId); 
     Map(x => x.LoginPassword); 
     Map(x => x.UserFirstName); 
     Map(x => x.UserSurname); 
     References(x => x.UserOrganisation, "OrganisationId"); 
    } 
    } 

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

Я спросил мой вопрос здесь: How to identify a particular entity's Session Factory with Fluent NHibernate and Multiple Databases

+3

В этом случае, где вы используете атрибут? Я знаю, что это будет в конфигурации сопоставления, но любой шанс вы могли бы предоставить более подробную информацию о вашей реализации? Благодаря! – reallyJim

+0

Где атрибут FluentNHibernateDatabase и как вы определяете Fluently.Configure()? – CallMeLaNN

+0

Атрибут является моим собственным, и я использую его для идентификации БД, к которой должен быть зарегистрирован конкретный класс (параметр для атрибута - это имя, которое я дал моей БД). Я реализовал такое, что у меня есть то, что я считаю «стандартным» БД, и все файлы Map, относящиеся к объектам в этой БД, не нуждаются в этом атрибуте (или, наоборот: все файлы карт без атрибута предполагаются нацеленными на DB по умолчанию). – Trevor

1

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

Было бы здорово, если бы FNH мог предоставить какую-то встроенную поддержку multi-db, но я не знаю, как это действительно можно было сделать; возможно, какой-то словарь SessionFactories, но каждая ситуация настолько уникальна.

НТН,
Berryl

/// <summary> 
    /// This would simply call <see cref="AutoMapHelpers.GetAutoMappingFilter"/> but we need to 
    /// exclude <see cref="LegacyProject"/> also for now. 
    /// </summary> 
    private static bool _getIncludedTypesFilter(Type t) { 
     return _isNotLegacy(t) && AutoMapHelpers.GetAutoMappingFilter(t); 
    } 
    private static bool _isNotLegacy(Type t) { return !t.Equals(typeof(LegacyProject)); } 
4

Самый простой способ сделать это, чтобы положить имя базы данных в схему

Тогда, при условии, что все столы доступны на ту же строку подключения, требуется только один сеанс завод

0

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

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