Свободный NHibernate + несколько баз данных - PullRequest
9 голосов
/ 17 апреля 2010

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

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

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

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

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

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

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

Ответы [ 4 ]

6 голосов
/ 23 апреля 2010

Я реализовал именно это, используя (мой собственный) атрибут в файле отображения Fluent, чтобы указать, к какой БД принадлежит объект. У меня также есть концепция базы данных «по умолчанию», и файлы отображения без атрибута предполагается, что он находится в БД по умолчанию (это может сократить количество классов, которые нужно декорировать). Затем у меня есть код инициализации, который создает фабрику сеансов для каждой базы данных и для каждого использует отражение, чтобы найти все классы 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");
    }
  }

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

Я задал свой вопрос здесь: Как идентифицировать фабрику сеансов конкретной сущности с помощью свободно распространяемой NHibernate и нескольких баз данных

5 голосов
/ 28 марта 2012

Простой способ сделать это - поместить имя базы данных в схему

public sealed class CustomerMapping: ClassMap<Customer>
{
    public CustomerMapping()
    {
        Schema("Northwind.dbo");
        Table("Customer");
    }
}

public sealed class Customer2Mapping: ClassMap<Customer2>
{
    public CustomerMapping()
    {
        Schema("Northwind2.dbo");
        Table("Customer");
    }
}

Тогда, при условии, что все таблицы доступны в одной строке соединения, вам нужна только одна фабрика сеансов

1 голос
/ 17 апреля 2010

Вы также можете фильтровать по типам. Вот строка прокомментированного кода из «зеленого поля» AutoPersistenceModel, который я использую в той же сборке, что и «коричневое поле один» (т.е. две базы данных) Но есть только один тип, который мне нужно отфильтровать, поэтому я не потрудился выделить устаревшую сборку. Если у вас их много на дБ, тогда разделение их по сборкам, вероятно, будет лучшим 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)); }
0 голосов
/ 30 июня 2012

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

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

...