优化的NHibernate会话工厂,Web应用程序的启动时间很慢 [英] Optimizing nhibernate session factory, startup time of webApp really slow

查看:236
本文介绍了优化的NHibernate会话工厂,Web应用程序的启动时间很慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有实现的测试​​应用程序。它使用功能NHibernate映射到MSSQL数据库里db对象。因为我想学习微调nhib。 MVC3应用程序,我使用这个应用程序。为测试它只有10枚举的属性和一个字符串属性一个简单的实体的目的。
所以,它是真正的光波,但根据NHibernate的探查器的启动时间是4.37秒。这是与呈现几行一个实体很慢选中/取消选中属性。



代码如下。
Domain.SessionProvider.cs



 公共静态ISessionFactory CreateSessionFactory()
{
无功配置= Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(C => c.FromConnectionStringWithKey(则myConnection)))
.Mappings (M = GT; m.FluentMappings.Add< FeaturesMap>())
.ExposeConfiguration(p => p.SetProperty(current_session_context_class,网络))
.BuildConfiguration();

返回config.BuildSessionFactory();
}



的Global.asax



 公共类MvcApplication:System.Web.HttpApplication 
{
// SessionPerWebRequest这里ommited以及其他内容
酒店的公共静态ISessionFactory SessionFactory的=
SessionProvider.CreateSessionFactory();

保护无效的Application_Start()
{
SessionFactory.OpenSession();
}
}

在myController的我有以下几点:

 公众的ActionResult指数()
{
返回查看(的GetData());
}

私人的IList< FeaturesViewModel>的GetData()
{
名单,LT;功能与GT;数据;使用
(ISession的会话= MvcApplication.SessionFactory.GetCurrentSession())
{使用
(ITransaction TX = session.BeginTransaction())
{
数据=会话。查询<特色方式>()采取(5).ToList();
tx.Commit();

VAR viewModelData = FeaturesViewModel.FromDomainModel(数据);
返回viewModelData;
}
}
}


解决方案

您可以通过缓存配置提高启动时间(Web和Windows应用程序)。下面的类会做这项工作:

 使用System.IO; 
使用的System.Reflection;
使用System.Runtime.Serialization.Formatters.Binary;
使用的System.Web;
使用NHibernate.Cfg;

命名空间NH32AutoMap.Core
{
公共类ConfigurationFileCache
{
私人只读字符串_cacheFile;
私人只读大会_definitionsAssembly;

公共ConfigurationFileCache(大会definitionsAssembly)
{
_definitionsAssembly = definitionsAssembly;
_cacheFile =nh.cfg;
如果(HttpContext.Current!= NULL)//为网络应用
_cacheFile = HttpContext.Current.Server.MapPath(
的String.Format(〜/ App_Data文件/ {0} ,_cacheFile)
);
}

公共无效DeleteCacheFile()
{
如果(File.Exists(_cacheFile))
File.Delete(_cacheFile);
}

公共BOOL IsConfigurationFileValid
{
得到
{
如果(!File.Exists(_cacheFile))
返回假;
变种configInfo =新的FileInfo(_cacheFile);
变种asmInfo =新的FileInfo(_definitionsAssembly.Location);

如果(configInfo.Length小于5 * 1024)
返回FALSE;

返回configInfo.LastWriteTime> = asmInfo.LastWriteTime;
}
} $ B使用
$ B公共无效SaveConfigurationToFile(配置配置)
{
(var文件= File.Open(_cacheFile,FileMode.Create))
{
变种BF =新的BinaryFormatter();
bf.Serialize(文件,配置);
}
}

公共配置LoadConfigurationFromFile()
{
如果
返回NULL(IsConfigurationFileValid!);

使用(var文件= File.Open(_cacheFile,FileMode.Open,FileAccess.Read))
{
变种BF =新的BinaryFormatter();
返回bf.Deserialize(文件)作为配置;
}
}
}
}

要使用,

 专用配置readConfigFromCacheFileOrBuildIt()
{
配置nhConfigurationCache;
变种nhCfgCache =新ConfigurationFileCache(MappingsAssembly);
VAR cachedCfg = nhCfgCache.LoadConfigurationFromFile();
如果(cachedCfg == NULL)
{
nhConfigurationCache = buildConfiguration();
nhCfgCache.SaveConfigurationToFile(nhConfigurationCache);
}
,否则
{
nhConfigurationCache = cachedCfg;
}
返回nhConfigurationCache;
}



,然后调用BuildSessionFactory之前,我们可以读取缓存中的配置文件或如果映射已经改变,建立并再次缓存它:

 公共ISessionFactory SetUpSessionFactory()
{
变种配置= readConfigFromCacheFileOrBuildIt();
VAR SessionFactory的= config.BuildSessionFactory();



在这里,你可以找到一个完整的示例:(的 ^ )。
+如果你想它的工作,不同的领域类和映射定义组件从主应用程序的组件(因为ConfigurationFileCache类将删除缓存文件,如果映射定义组件比缓存文件的LastWriteTime是新的)。


I have implement testing app. which uses fluent nhibernate mapping to db object inside mssql db. Since I want to learn fine tune nhib. mvc3 applications, I'm using this app. for testing purposes which have only one simple entity with 10 enum properties and one string property. So, it is really lightwave, yet startup time according to nhibernate profiler is 4.37 sec. Which is really slow for rendering one entity with few lines checked/unchecked property.

Code is the following. Domain.SessionProvider.cs

public static ISessionFactory CreateSessionFactory()
{
   var config = Fluently.Configure()
          .Database(MsSqlConfiguration.MsSql2008
          .ConnectionString(c => c.FromConnectionStringWithKey("myConnection")))
          .Mappings(m => m.FluentMappings.Add<FeaturesMap>())
          .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();
    }
}

Inside myController I have following:

public ActionResult Index()
{
   return View(GetData());
}

private IList<FeaturesViewModel> GetData()
{
     List<Features> data;
     using (ISession session = MvcApplication.SessionFactory.GetCurrentSession())
     {
          using (ITransaction tx = session.BeginTransaction())
          {
              data = session.Query<Features>().Take(5).ToList();
              tx.Commit();

              var viewModelData = FeaturesViewModel.FromDomainModel(data);
              return viewModelData;
           }
      }
}

解决方案

You can improve the startup time (of both web and windows applications) by caching the Configurations. The following class will do this job:

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;
            }
        }
    }
}

To use that,

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;
}

And then before calling the BuildSessionFactory, we can read the config file from cache or if the mappings have changed, build it and cache it again:

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

Here you can find a full sample: (^). + If you want to make it work, separate domain classes and mappings definitions assemblies from the main application's assembly (because the ConfigurationFileCache class will delete the cache file if the mappings definitions assembly is newer than the cache file's LastWriteTime).

这篇关于优化的NHibernate会话工厂,Web应用程序的启动时间很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆