让NHibernate在同一个应用程序中连接多个数据库

在开发一些项目时,会使用到多个数据库。例如类A保存在数据库A,类B保存在数据库B。NHibernate在BuildSessionFactory之后,ISessionFactory就不能改变数据库的连接,即是说一个ISessionFactory只能对应一个数据库连接。但NHibernate可以在同一个应用中实例化多个ISessionFactory。实例化多个ISessionFactory,并让类A或类B找到自己所对应的ISessionFactory,获取ISession,即可实现多数据库连接。

如何通过类型获取ISessionFactory呢?ISessionFactory的Statistics.EntityNames中保存了所有映射了的实体类的类名。我们可以判断实体类的类名是否在EntityNames中,确定实体类所对应的ISessionFactory。

根据类型获取ISessionFactory:

1 public interface ISessionFactoryHolder
2 {
3 ISessionFactory GetSessionFactoryForEntity<TEntity>() where TEntity : IEntity;
4 }
5
6  public class SessionFactoryHolder : ISessionFactoryHolder
7 {
8 private IDictionary<string, int> entityDictionary;
9 private IDictionary<int, ISessionFactory> factoryDictionary;
10
11 public SessionFactoryHolder()
12 {
13 this.entityDictionary = new Dictionary<string, int>();
14 this.factoryDictionary = new Dictionary<int, ISessionFactory>();
15 }
16
17 #region ISessionFactoryHolder Members
18
19 public ISessionFactory GetSessionFactoryForEntity<TEntity>() where TEntity : IEntity
20 {
21 int hashCode = 0;
22
23 Asserts.Assert<MappingException>(
24 this.EntityInDictionary(typeof(TEntity).FullName, out hashCode) == false
25 , string.Format("No persister for:{0}", typeof(TEntity).FullName));
26
27 return this.factoryDictionary[hashCode];
28 }
29
30 #endregion
31
32 public void RegisterSessionFactory(ISessionFactory sessionFactory)
33 {
34 Asserts.IsNotNull(sessionFactory, "sessionFactory");
35
36 this.factoryDictionary[sessionFactory.GetHashCode()] = sessionFactory;
37
38 this.MapingEntityNameToSessionFactoryHashCode(sessionFactory.Statistics.EntityNames
39 , sessionFactory.GetHashCode());
40 }
41
42 private bool EntityInDictionary(string entityName, out int sessionFactoryHashCode)
43 {
44 return this.entityDictionary.TryGetValue(entityName, out sessionFactoryHashCode);
45 }
46
47 private void MapingEntityNameToSessionFactoryHashCode(string[] entityNames, int sessionFactoryHashCode)
48 {
49 foreach (var entityName in entityNames)
50 {
51 this.entityDictionary[entityName] = sessionFactoryHashCode;
52 }
53 }
54 }

根据类型获取ISession:

1 public interface ISessionHolder : IDisposable
2 {
3 ISession GetSessionForEntity<TEntity>() where TEntity : IEntity;
4 }
5  public class SessionHolder : ISessionHolder, IUnitOfWork
6 {
7 private readonly ISessionFactoryHolder factoryHolder;
8 private IDictionary<int, ISession> sessionDictionary;
9
10 public SessionHolder(ISessionFactoryHolder factoryHolder)
11 {
12 Asserts.IsNotNull(factoryHolder, "factoryHolder");
13
14 this.factoryHolder = factoryHolder;
15 this.sessionDictionary = new Dictionary<int, ISession>();
16 }
17
18 #region ISessionHolder Members
19
20 public ISession GetSessionForEntity<TEntity>() where TEntity : IEntity
21 {
22 if (this.sessionDictionary.ContainsKey(this.GetFactoryHashCode<TEntity>()) == false)
23 {
24 this.sessionDictionary[this.GetFactoryHashCode<TEntity>()] = this.OpenNewSession<TEntity>();
25 }
26
27 return this.sessionDictionary[this.GetFactoryHashCode<TEntity>()];
28 }
29
30 #endregion
31
32 #region IDisposable Members
33 //Dispose Code
34   #endregion
35
36 #region IUnitOfWork
37 //IUnitOfWork
38 #endregion
39
40 private ISessionFactory GetFactory<TEntity>() where TEntity : IEntity
41 {
42 return this.factoryHolder.GetSessionFactoryForEntity<TEntity>();
43 }
44
45 private int GetFactoryHashCode<TEntity>() where TEntity : IEntity
46 {
47 return this.GetFactory<TEntity>().GetHashCode();
48 }
49
50 private ISession OpenNewSession<TEntity>() where TEntity : IEntity
51 {
52 return this.GetFactory<TEntity>().OpenSession();
53 }
54 }

Repository:

1 public interface IRepository<TEntity> where TEntity : IEntity
2 {
3 void Save(TEntity entity);
4 //......
5 }
6
7 public class NHibernateRepository<TEntity> : IRepository<TEntity> where TEntity : IEntity
8 {
9 private readonly ISessionHolder sessionHolder;
10
11 public NHibernateRepository(ISessionHolder sessionHolder)
12 {
13 Asserts.IsNotNull(sessionHolder, "sessionHolder");
14
15 this.sessionHolder = sessionHolder;
16 }
17
18 protected virtual ISession Session
19 {
20 get
21 {
22 return this.sessionHolder.GetSessionForEntity<TEntity>();
23 }
24 }
25
26 public override void Save(TEntity entity)
27 {
28 this.Session.Save(entity);
29 }
30 //......
31 }

posted on 2011-05-18 13:08  碳素墨水  阅读(2201)  评论(5编辑  收藏  举报