NHibernate Fluent - 多数据库配置

NHibernate Fluent - Multiple databases configuration

我正在使用 Fluent Nhibernate 来自:https://github.com/jagregory/fluent-nhibernate

是否可以针对不同的数据库(不同的连接字符串)进行多个配置

            builder.Register(c =>
            Fluently.Configure()
                .Database(DatabaseConfiguration)  // <-- Connection string 1
                .Mappings(AutoMapping.Configurations)
                .ExposeConfiguration(cfg => cfg.SetProperty("connection.isolation", "ReadCommitted"))
                .ExposeConfiguration(cfg => cfg.SetProperty(Environment.CommandTimeout, c.Resolve<IConfig>().SqlCommandTimeoutSeconds.ToString()))
                .BuildConfiguration())
            .SingleInstance();

            builder.Register(c =>
            Fluently.Configure()
                .Database(ReportingDatabaseConfiguration) // <-- Connection string 2
                .Mappings(AutoMapping.Configurations)
                .ExposeConfiguration(cfg => cfg.SetProperty("connection.isolation", "ReadCommitted"))
                .ExposeConfiguration(cfg => cfg.SetProperty(Environment.CommandTimeout, c.Resolve<IConfig>().SqlCommandTimeoutSeconds.ToString()))
                .BuildConfiguration())
            .SingleInstance();

  builder.Register(c =>
            c.Resolve<Configuration>()
                .BuildSessionFactory())
            .SingleInstance();

此配置在 Autofac 中。

当前行为是后面的行为将覆盖第一个配置。

我的预期结果是 ISession 应该能够根据我查询的实体知道使用哪个数据库。

这可能吗?

注意:我已经尝试过http://devstoolbox.altervista.org/multiple-connections-using-nhibernate/中提到的解决方案 但对我不起作用。

让 nhibernate 根据实体找出要使用的连接(会话)可能是不可能的,甚至是一个很好的主意。如果您加入不同数据库的两个实体怎么办。预期的结果是什么?

如果您在回购或查询 class 中请求 "right" 会话怎么办?你应该有上下文,在这个 class 中你期望查询到 运行 的数据库。对吗?

您注册一个 NH-Connection-Class,它将 return 一个可配置的 NHibernate SessionFactory

public class NHConnection
{
 private string _connectionString;
 private Type _markerType;

 public WithConnectionString(string connectionString)
 {
  _connectionString = connectionString;
  return this;
 }

 public NHConnection UseMarkerAssembly(Type markerAssembly)
    {
        _markerType = markerAssembly;
        return this;
    }

 public ISessionFactory Build()
 {
   var config = Fluently.Configure()
            .Database(_connectionString) // <-- Connection string 2

            //.Mappings(AutoMapping.Configurations) consider using a configurable markerAssembly for each db like:
            .Mappings(m =>
            {
                m.FluentMappings.AddFromAssembly(markerType.Assembly)
            });

            .ExposeConfiguration(cfg => cfg.SetProperty("connection.isolation", "ReadCommitted"))
            .ExposeConfiguration(cfg => cfg.SetProperty(Environment.CommandTimeout, c.Resolve<IConfig>().SqlCommandTimeoutSeconds.ToString()))
            .BuildConfiguration());
    return config.BuildSessionFactory();
 }
}

 //Register the FactoryBuilder in your Autofac Module

 builder.Register(x => new NHConnection().WithConnectionString("your;connectionString:toDb1").UseMarkerAssembly(typeof(MarkerTypeAssemblyForDB1Mappings)).Build()).Keyed<ISessionFactory>("db1").SingleInstance();
 builder.Register(x => new NHConnection().WithConnectionString("your;connectionString:toDb2").UseMarkerAssembly(typeof(MarkerTypeAssemblyForDB2Mappings)).Build()).Keyed<ISessionFactory>("db2").SingleInstance();
 builder.Register<Func<string, ISessionFactory>>(c =>
        {
            IComponentContext co = c.Resolve<IComponentContext>();
            return db => co.ResolveKeyed<ISessionFactory>(db);
        });     


 // Resolve the factory for DB 1, 2 or 3 in your query / repo class      

 public class QueryClass{
   private _factoryLookUp Func<string, ISessionFactory> FactoryLookup { get; set; }
   public void QueryClass(Func<DataDomain, ISessionFactory> factoryLookup)
   {
    _factoryLookUp = factoryLookup; 
   }

   public executeYourQuery()
   {
     using(var session = factoryLookup("db1").OpenSession)
     {
       ....
     }
   }

 }