构建Session Factory时Fluent-NHibernate能否使用NHibernate.Cfg.Configuration?
用NHibernate配置构建FluentNHibernate Session Factory的问题与修正
问题说明
希望通过NHibernate的xml配置文件来构建FluentNHibernate的Session Factory,但不确定现有代码中的委托及Invoke调用是否正确。现有代码如下:
1. Session Factory构建代码
lock (_factorylock) { if (_factory == null) { nHibernateConfig = delegate { GetConfiguration(); }; nHibernateConfig.Invoke(GetConfiguration()); var cfg = Fluently.Configure(). Database(MsSqlConfiguration.MsSql2012) .ExposeConfiguration( nHibernateConfig) .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>()); _factory = cfg.BuildSessionFactory(); } }
2. GetConfiguration方法
private static NHibernate.Cfg.Configuration GetConfiguration() { var configuration = new NHibernate.Cfg.Configuration(); var baseDirectory = AppDomain.CurrentDomain.BaseDirectory; var configFile = Directory.GetFiles(baseDirectory, ConfigFile, SearchOption.AllDirectories).FirstOrDefault(); return configuration.Configure(configFile); }
3. NHibernate xml配置文件
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <session-factory> <property name="dialect">NHibernate.Dialect.MsSql2012Dialect, NHibernate</property> <property name="connection.connection_string">Database=authentication; Port=3306; Server=127.0.0.1; Uid=root; Pwd=; persistsecurityinfo=True;SslMode=none </property> <property name="adonet.batch_size">100</property> </session-factory> </hibernate-configuration>
修正方案
原代码存在两处核心问题:委托类型不匹配、配置逻辑冲突,以下是修正后的实现:
1. 核心错误点说明
- 委托定义错误:
ExposeConfiguration需要的是Action<NHibernate.Cfg.Configuration>类型的委托(接收一个Configuration参数),但原代码中定义的是无参委托,完全不符合要求。 - Invoke调用冗余且错误:原代码中手动调用委托的操作完全多余,
ExposeConfiguration会在FluentNHibernate生成配置后自动执行传入的委托;同时调用时传入GetConfiguration()的写法也是错误的,无参委托不需要参数。 - 配置冲突:同时使用
Database(MsSqlConfiguration.MsSql2012)和xml配置会导致覆盖,MsSqlConfiguration会替换xml中的连接字符串、方言等设置,若要使用xml配置需去掉该方法调用。
2. 修正后的Session Factory构建代码
如果要完全基于xml配置构建,正确的写法是直接将GetConfiguration()的结果传入Fluently.Configure的构造函数:
lock (_factorylock) { if (_factory == null) { // 获取从xml加载的NHibernate配置 var nhConfig = GetConfiguration(); // 基于已有配置构建FluentNHibernate Session Factory var cfg = Fluently.Configure(nhConfig) .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>()); _factory = cfg.BuildSessionFactory(); } }
3. 若需额外修改配置(可选)
如果需要在xml配置的基础上用ExposeConfiguration做额外调整,写法如下:
lock (_factorylock) { if (_factory == null) { var nhConfig = GetConfiguration(); var cfg = Fluently.Configure(nhConfig) .ExposeConfiguration(config => { // 在这里对配置做额外修改,比如添加拦截器、调整缓存设置等 // config.SetInterceptor(new CustomInterceptor()); }) .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>()); _factory = cfg.BuildSessionFactory(); } }
4. 补充说明
- 确保
GetConfiguration中的ConfigFile变量是正确的配置文件名(比如"hibernate.cfg.xml"),且文件存在于项目输出目录中。 - 若xml配置中已经指定了方言和连接字符串,无需再通过
MsSqlConfiguration.MsSql2012重复设置,避免冲突。
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

