在.netcore中使用Fluent Nhibernate访问多个数据库



我是NHIBERNATE的新手,并尝试将其与.NET Core一起用于多个SQL Server数据库。我已经浏览了文档并创建了IsessionFactoty并在启动中进行了配置,但是当我尝试以存储库方法访问会话对象时,我会遇到错误,因为它仅在一个数据库中查看,即DBConnectionsTring

我的startup.cs看起来像

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());

这是我的存储库类,我从控制器

来调用它
public class BusinessRepo
    {
        ISession _session;
        public BusinessRepo(ISession session)
        {
            _session = session;
        }
        //This method needs to use DbConnectionString
        public PersonGeo GetPersonById(string personId)
        {
            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()
        {
            //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();
        }
    }

这是我的存储库类,我从控制器

来调用它
  var person = _repo.GetPersonById(personId);
  var allUser = _repo.GetAllUsers();

,我发现找不到对象名称" 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());

然后,将SessionFactory注入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();
        }
    }

您仍然可以通过创建将数据库名称作为参数并返回Isession对象而不是在每个方法

中进行的另一种方法来重构。

我有一段时间有类似的问题,我创建了一个负责管理多个Session factory

的类

在startup.cs

services.AddSingleton<ISessionSource, SessionSource>();

和class 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))

最新更新