C# 使用.netcore中的fluent nhibernate访问多个数据库
我是nHibernate的新手,尝试将其与.Net core一起用于多个sql server数据库。我查看了文档,创建了ISessionFactory并在启动时对其进行了配置,但当我尝试在repository方法中访问会话对象时,我遇到了错误,因为它只在一个数据库中查找,即DbConnectionString 我的startup.cs看起来像这样C# 使用.netcore中的fluent nhibernate访问多个数据库,c#,.net,sql-server,asp.net-core,fluent-nhibernate,C#,.net,Sql Server,Asp.net Core,Fluent Nhibernate,我是nHibernate的新手,尝试将其与.Net core一起用于多个sql server数据库。我查看了文档,创建了ISessionFactory并在启动时对其进行了配置,但当我尝试在repository方法中访问会话对象时,我遇到了错误,因为它只在一个数据库中查找,即DbConnectionString 我的startup.cs看起来像这样 var sessionFactory = Fluently .Configure()
var sessionFactory = Fluently
.Configure()
.Database(() =>
{
return FluentNHibernate.Cfg.Db.MsSqlConfiguration
.MsSql2008
.ShowSql()
.ConnectionString(Configuration.GetConnectionString("DbConnectionString"));
})
.Database(() =>
{
return FluentNHibernate.Cfg.Db.MsSqlConfiguration
.MsSql2008
.ShowSql()
.ConnectionString(Configuration.GetConnectionString("AdminDbConnectionString"));
})
.BuildSessionFactory();
services.AddSingleton<NHibernate.ISession>(factory => nHIbernateSession.OpenSession());
我得到了找不到的对象名“tableName”,因为_session对象正在查看另一个数据库。有人知道如何实施吗?将您的启动更改为
var dbSessionFatory = Fluently
.Configure()
.Database(() =>
{
return FluentNHibernate.Cfg.Db.MsSqlConfiguration
.MsSql2008
.ShowSql()
.ConnectionString(Configuration.GetConnectionString("DbConnectionString"));
})
.BuildSessionFactory();
var adminDbSessionFactory= Fluently
.Configure()
.Database(() =>
{
return FluentNHibernate.Cfg.Db.MsSqlConfiguration
.MsSql2008
.ShowSql()
.ConnectionString(Configuration.GetConnectionString("AdminDbConnectionString"));
})
.BuildSessionFactory();
services.AddSingleton<NHibernate.ISession>(factory => dbSessionFatory.OpenSession());
services.AddSingleton<NHibernate.ISession>(factory => adminDbSessionFactory.OpenSession());
var dbSessionFatory=流利
.Configure()
.数据库(()=>
{
return FluentNHibernate.Cfg.Db.MsSqlConfiguration
.MsSql2008
.ShowSql()
.ConnectionString(Configuration.GetConnectionString(“DbConnectionString”);
})
.BuildSessionFactory();
var administrationfactory=流畅
.Configure()
.数据库(()=>
{
return FluentNHibernate.Cfg.Db.MsSqlConfiguration
.MsSql2008
.ShowSql()
.ConnectionString(Configuration.GetConnectionString(“AdminDbConnectionString”);
})
.BuildSessionFactory();
services.AddSingleton(工厂=>dbSessionFatory.OpenSession());
services.AddSingleton(factory=>adminDbSessionFactory.OpenSession());
然后将Sessionfactory的IEnumerable注入repositoy方法,并使用特定的Sessionfactory作为所需的数据库
public class BusinessRepo
{
private IEnumerable<ISession> _sessions;
public BusinessRepo(IEnumerable<ISession> sessions)
{
_sessions = sessions;
}
//This method needs to use DbConnectionString
public PersonGeo GetPersonById(string personId)
{
var _session = _sessions.Where(a => a.Connection.Database == "DbName").FirstOrDefault();
var value = _session.CreateCriteria<PersonGeo>()
.Add(Restrictions.Eq("Person_ID", personId))
.SetCacheable(true)
.SetCacheMode(CacheMode.Normal)
.List<PersonGeo>();
return value.FirstOrDefault();
}
//This method needs to used AdminDbConnectionString
public List<User> GetAllUsers()
{
var _session = _sessions.Where(a => a.Connection.Database == "DbName").FirstOrDefault();
//If I debug the _session and look for connection string it is taking "DbConnectionstring (which is configured first in startup)"
var result = _session.CreateSQLQuery("SELECT UserID,UserName,Email,IsActive FROM Users").List<User>();
return result();
}
}
公共类BusinessRepo
{
私人IEnumerable_会议;
公共业务报告(IEnumbersessions)
{
_会话=会话;
}
//此方法需要使用DbConnectionString
public PersonGeo GetPersonById(字符串personId)
{
var\u session=\u sessions.Where(a=>a.Connection.Database==“DbName”).FirstOrDefault();
var值=_session.CreateCriteria()
.Add(Restrictions.Eq(“Person_ID”,personId))
.SetCacheable(真)
.SetCacheMode(CacheMode.Normal)
.List();
返回值.FirstOrDefault();
}
//此方法需要使用AdminDbConnectionString
公共列表GetAllUsers()
{
var\u session=\u sessions.Where(a=>a.Connection.Database==“DbName”).FirstOrDefault();
//如果调试_会话并查找连接字符串,它将使用“DbConnectionstring(在启动时首先配置)”
var result=_session.CreateSQLQuery(“选择UserID、UserName、Email、isactivefrom Users”).List();
返回结果();
}
}
您仍然可以通过创建另一个方法来重构它,该方法将数据库名称作为参数,并返回ISession对象,而不是在每个方法中都执行此操作 在Startup.cs中
services.AddSingleton<ISessionSource, SessionSource>();
打开配置为单例的会话不是一个好主意。您希望利用连接池,尽可能晚地打开会话,并尽快关闭会话,以便将连接返回到池中。在本文中,将解释如何使用依赖项注入容器而不是内置容器来管理命名实例。您可以插入asp.net核心更高级的依赖项注入容器,如autofact,它允许您使用命名实例。这个想法不错。只需考虑每次需要连接时不想调用BudidStudio工厂。BuildSessionFactory是一项昂贵的任务,在启动时只能调用一次。
public class BusinessRepo
{
private IEnumerable<ISession> _sessions;
public BusinessRepo(IEnumerable<ISession> sessions)
{
_sessions = sessions;
}
//This method needs to use DbConnectionString
public PersonGeo GetPersonById(string personId)
{
var _session = _sessions.Where(a => a.Connection.Database == "DbName").FirstOrDefault();
var value = _session.CreateCriteria<PersonGeo>()
.Add(Restrictions.Eq("Person_ID", personId))
.SetCacheable(true)
.SetCacheMode(CacheMode.Normal)
.List<PersonGeo>();
return value.FirstOrDefault();
}
//This method needs to used AdminDbConnectionString
public List<User> GetAllUsers()
{
var _session = _sessions.Where(a => a.Connection.Database == "DbName").FirstOrDefault();
//If I debug the _session and look for connection string it is taking "DbConnectionstring (which is configured first in startup)"
var result = _session.CreateSQLQuery("SELECT UserID,UserName,Email,IsActive FROM Users").List<User>();
return result();
}
}
services.AddSingleton<ISessionSource, SessionSource>();
public class SessionSource : ISessionSource
{
private static readonly object _lockObject = new object();
private static Dictionary<string, ISessionFactory> _sessionFactories = new Dictionary<string, ISessionFactory>();
public SessionSource()
{}
public ISession GetSession(int csName)
{
lock (_lockObject)
{
var session = GetSessionFactory(csName).OpenSession();
return session;
}
}
private FluentConfiguration BaseConfiguration()
{
return Fluently.Configure()
.Mappings(x => x.FluentMappings.AddFromAssemblyOf<MappingCandidate>())
.ExposeConfiguration(cfg =>
{
new SchemaExport(cfg)
.Execute(false, false, false);
});
}
private Configuration AssembleConfiguration(string connectionString)
{
return BaseConfiguration()
.Database(() =>
{
return FluentNHibernate.Cfg.Db.MsSqlConfiguration
.MsSql2012
.ConnectionString(connectionString);
})
.BuildConfiguration();
}
private ISessionFactory GetSessionFactory(int csName)
{
var connectionString = Configuration.GetConnectionString(csName);
if (_sessionFactories.ContainsKey(connectionString))
{
return _sessionFactories[connectionString];
}
var sessionFactory = AssembleConfiguration(connectionString).BuildSessionFactory();
_sessionFactories.Add(connectionString, sessionFactory);
return sessionFactory;
}
}
using (var session = _sessionSource.GetSession(connectionStringName))