views:

345

answers:

2

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.

+1  A: 

Hi Pablote

You can also filter by types. Here's a line of commented code from a "green field" AutoPersistenceModel I use in the same assembly as a "brown field one" (ie, two databases). But there is only one type I need to filter on, so I haven't bothered to split out a legacy assembly. If you have got lots of them per db then splitting them by assemblies is probably going to be best IMO.

It would be cool if FNH could provide some sort of built in multi-db support but I don't know how that really could be done; some sort of dictionary of SessionFactories maybe but every situation is just so unique.

HTH,
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)); }
Berryl
A: 

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: http://stackoverflow.com/questions/2698503/how-to-identify-a-particular-entitys-session-factory-with-fluent-nhibernate-and

Trevor
In this scenario, where are you making use of the attribute? I know it would be in the mapping configuration, but any chance you could provide more detail of your implementation? Thanks!
reallyJim