NHibernate Fluent - 多个数据库配置

时间:2017-10-23 05:17:17

标签: c# nhibernate fluent-nhibernate autofac

我使用的是Fluent Nhibernate:https://github.com/jagregory/fluent-nhibernate

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

(37,24): error TS2339: Property 'className' does not exist on type
   'IntrinsicAttributes & IntrinsicClassAttributes<Component<Pick<{ 
      current: Project | undefined; } &...'.

此配置位于Autofac。

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

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

这可能吗?

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

1 个答案:

答案 0 :(得分:1)

让nhibernate找出基于实体使用的连接(Session)可能是不可能的,甚至是一个非常好的主意。如果您加入两个不同dbs的实体,该怎么办?什么是预期的结果?

如果您要求&#34;权利&#34;该怎么办?您的repo-或查询类中的会话?您应该拥有上下文,您希望查询在此类中运行的数据库。正确?

您注册一个NH-Connection-Class,它将返回一个可配置的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)
     {
       ....
     }
   }

 }