优化nhibernate会话工厂,webApp的启动时间确实很慢

我已经实施了测试应用。 它使用流畅的nhibernate映射到mssql db中的db对象。 因为我想学习微调nhib。 mvc3应用程序,我正在使用这个应用程序。 用于测试目的,它只有一个带有10个枚举属性和一个字符串属性的简单实体。 所以,它实际上是光波,但根据nhibernate profiler的启动时间是4.37秒。 这对于渲染一个具有少量行检查/未检查属性的实体来说真的很慢。

代码如下。 Domain.SessionProvider.cs

public static ISessionFactory CreateSessionFactory() { var config = Fluently.Configure() .Database(MsSqlConfiguration.MsSql2008 .ConnectionString(c => c.FromConnectionStringWithKey("myConnection"))) .Mappings(m => m.FluentMappings.Add()) .ExposeConfiguration(p => p.SetProperty("current_session_context_class", "web")) .BuildConfiguration(); return config.BuildSessionFactory(); } 

Global.asax中

 public class MvcApplication : System.Web.HttpApplication { //SessionPerWebRequest is ommited here as well as other content public static ISessionFactory SessionFactory = SessionProvider.CreateSessionFactory(); protected void Application_Start() { SessionFactory.OpenSession(); } } 

在myController里面我有以下内容:

 public ActionResult Index() { return View(GetData()); } private IList GetData() { List data; using (ISession session = MvcApplication.SessionFactory.GetCurrentSession()) { using (ITransaction tx = session.BeginTransaction()) { data = session.Query().Take(5).ToList(); tx.Commit(); var viewModelData = FeaturesViewModel.FromDomainModel(data); return viewModelData; } } } 

您可以通过缓存配置来改善(Web和Windows应用程序)的启动时间。 以下课程将完成这项工作:

 using System.IO; using System.Reflection; using System.Runtime.Serialization.Formatters.Binary; using System.Web; using NHibernate.Cfg; namespace NH32AutoMap.Core { public class ConfigurationFileCache { private readonly string _cacheFile; private readonly Assembly _definitionsAssembly; public ConfigurationFileCache(Assembly definitionsAssembly) { _definitionsAssembly = definitionsAssembly; _cacheFile = "nh.cfg"; if (HttpContext.Current != null) //for the web apps _cacheFile = HttpContext.Current.Server.MapPath( string.Format("~/App_Data/{0}", _cacheFile) ); } public void DeleteCacheFile() { if (File.Exists(_cacheFile)) File.Delete(_cacheFile); } public bool IsConfigurationFileValid { get { if (!File.Exists(_cacheFile)) return false; var configInfo = new FileInfo(_cacheFile); var asmInfo = new FileInfo(_definitionsAssembly.Location); if (configInfo.Length < 5 * 1024) return false; return configInfo.LastWriteTime >= asmInfo.LastWriteTime; } } public void SaveConfigurationToFile(Configuration configuration) { using (var file = File.Open(_cacheFile, FileMode.Create)) { var bf = new BinaryFormatter(); bf.Serialize(file, configuration); } } public Configuration LoadConfigurationFromFile() { if (!IsConfigurationFileValid) return null; using (var file = File.Open(_cacheFile, FileMode.Open, FileAccess.Read)) { var bf = new BinaryFormatter(); return bf.Deserialize(file) as Configuration; } } } } 

要使用它,

 private Configuration readConfigFromCacheFileOrBuildIt() { Configuration nhConfigurationCache; var nhCfgCache = new ConfigurationFileCache(MappingsAssembly); var cachedCfg = nhCfgCache.LoadConfigurationFromFile(); if (cachedCfg == null) { nhConfigurationCache = buildConfiguration(); nhCfgCache.SaveConfigurationToFile(nhConfigurationCache); } else { nhConfigurationCache = cachedCfg; } return nhConfigurationCache; } 

然后在调用BuildSessionFactory之前,我们可以从缓存中读取配置文件,或者如果映射已更改,则构建它并再次缓存它:

 public ISessionFactory SetUpSessionFactory() { var config = readConfigFromCacheFileOrBuildIt(); var sessionFactory = config.BuildSessionFactory(); 

在这里您可以找到完整的样本:( ^ )。 +如果要使其工作,请从主应用程序的程序集中分离域类和映射定义程序集(因为如果映射定义程序集比缓存文件的LastWriteTime更新,ConfigurationFileCache类将删除缓存文件)。

正确地说,在HttpApplication(或其子类,如MvcApplication)的构造函数中创建对象不是一个好主意。 最好在Application_Start处理程序中创建会话工厂。

您应该删除NHibernate探查器(因为所有探查器都可能影响测量)。 相反,调用CreateSessionFactory()并使用Stopwatch类将其包围以获得准确的测量值。

您的数据库服务器响应缓慢吗? 由于连接池,这可能只在第一次出现时才会引起注意。

NHibernate确实需要一些时间进行初始化,但是使用一个轻量级实体的4秒似乎确实太多了。 这当然受到测试系统的一般性能的影响。