Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fluent NHibernate + multiple databases

My project needs to handle three databases, that means three session factories. The thing is if i do something like this with fluent nhibernate:

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

the factories would pick up all the mappings, even the ones that correspond to another database

I've seen that when using automapping you can do something like this, and filter by namespace:

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

I havent found anything like this for fluent mappings, is it possible?? The only solutions I can think of are: either create separate assemblies for each db mapping classes or explicitly adding each of the entities to the factory configuration.

I would prefer to avoid both, if possible. Thanks.

like image 236
Pablote Avatar asked Feb 03 '23 05:02

Pablote


2 Answers

I've implemented exactly this using (my own) Attribute on the Fluent mapping file to dictate which DB the entity belongs in. I've also got a concept of a 'default' database, and mapping files without an attribute are assumed to reside in the default DB (it may cut down on the number of classes you need to decorate). I then have initialisation code which creates a Session Factory per database, and for each, uses reflection to find all ClassMap classes,examines the attribute to determine which DB it belongs to, and registers each ClassMap accordingly.

A mapping file example:

  [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");
    }
  }

Obviously I've defined a list of the DBs that are referenced/used.
My implementation works so far as I've taken it, but I've hit a snag (that I hope someone can help out with):

I've asked my question here: How to identify a particular entity's Session Factory with Fluent NHibernate and Multiple Databases

like image 167
Trevor Avatar answered Feb 13 '23 07:02

Trevor


The easy way of doing this is to put the database name into the Schema

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");
    }
}

Then, provided all tables are accessible on the same connection string, you only need one session factory

like image 37
gls123 Avatar answered Feb 13 '23 06:02

gls123