pan*_*njo 3 c# nhibernate asp.net-mvc
我正在使用mvc3 nhibernate orm层和mssql db开发我的第一个应用程序.
这是我使用nhibernate创建的第一个应用程序,除了intiial responsn time,一切都很好.经过一些调查,我实现了每个Web请求的会话,这绝对是一个升级,我的实体在第一次调用后加载得更快,但我的问题仍然是一样的.
初始响应时间非常慢,当我键入domainname.com并按下enter等待时间约为.10-15秒 并且这不是内容的实际加载时间,在那之后10-15秒.我的网站开始加载,几秒钟.
是时候会话工厂必须初始化所有需要的"东西",但我认为它必须是别的东西.这是无法接受的.
我的应用程序在站点内存分配200 MB的winhost上运行,所以我认为这不是问题.
任何提示都是受欢迎的.如果您需要更多详细信息,请询问.
谢谢
更新: 在使用nhibernate profiler检查应用程序会话使用情况后,我发现了一些有趣的东西.由于我真的是使用探查器的初学者,我想我发现了昂贵的会话.在一般统计中,67个实体以36.571的持续时间加载,以秒为单位.这个秒值真的很奇怪,因为我有10-max 15秒加载.
第二次更新: global.asax
public class MvcApplication : System.Web.HttpApplication{
public static ISessionFactory SessionFactory =
MyDomain.Infrastructure.SessionProvider.CreateSessionFactory();
//My session factory is open in Application_Start() like this
SessionFactory.OpenSession();
}
Run Code Online (Sandbox Code Playgroud)
我正在使用流畅的方法来映射我的对象.所以我在域项目中的会话提供程序看起来像这样
//This should be used from web app, global.asax.cs calls
public static ISessionFactory CreateSessionFactory()
{
string conStringName = "ConnectionString";
var cfg = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.FromConnectionStringWithKey(conStringName)))
.Mappings(m => m.FluentMappings.Add<Entity1>())
.Mappings(m => m.FluentMappings.Add<Entity2>())
.Mappings(m => m.FluentMappings.Add<Entity3>())
.ExposeConfiguration(p => p.SetProperty("current_session_context_class", "web"))
.BuildConfiguration();
return cfg.BuildSessionFactory();
}
Run Code Online (Sandbox Code Playgroud)
更新3 仍然没有解决此问题的方法
更新4和最后 我的问题在sessionFactory中定义.我认为我的配置对象应该被序列化.如果有人能够表达如何使用我的代码显示如何做到这一点与流利conf.我很乐意接受他/她的回答.谢谢.
Rau*_*ess 12
很多细节都缺失了,但既然你说这是你的第一个NHibernate应用程序,我将推荐可能要检查的东西:
这些将是我的建议,代码看不见.
更新:所以主要问题似乎是10-15秒启动,这可能是Application_Start期间的SessionFactory初始化时间.
我还没有尝试过,但是快速启动时的一般建议是将NH Configuration对象序列化为磁盘(包含映射),并在每次启动时加载(原始缓存).如果映射发生更改,则需要检测该映射,否则执行手动加载(删除序列化配置文件).
在您的代码中,您使用Fluent NHibernate构建FluentNHibernate.Cfg.FluentConfiguration实例,并在其上调用cfg.BuildSessionFactory()以返回新的ISessionFactory.您需要序列化的配置是NHibernate.Cfg.Configuration.所以你可能会修改你的代码:
public static ISessionFactory CreateSessionFactory()
{
string conStringName = "ConnectionString";
// http://weblogs.asp.net/ricardoperes/archive/2010/03/31/speeding-up-nhibernate-startup-time.aspx
System.Runtime.Serialization.IFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
NHibernate.Cfg.Configuration cfg = null;
if (File.Exists("Configuration.serialized"))
{
using (Stream stream = File.OpenRead("Configuration.serialized"))
{
cfg = serializer.Deserialize(stream) as Configuration;
}
}
else
{
// file not exists, configure normally, and serialize NH configuration to disk
cfg = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.FromConnectionStringWithKey(conStringName)))
.Mappings(m => m.FluentMappings.Add<Entity1>())
.Mappings(m => m.FluentMappings.Add<Entity2>())
.Mappings(m => m.FluentMappings.Add<Entity3>())
.ExposeConfiguration(p => p.SetProperty("current_session_context_class", "web"))
.BuildConfiguration();
using (Stream stream = File.OpenWrite("Configuration.serialized"))
{
serializer.Serialize(stream, cfg);
}
}
return cfg.BuildSessionFactory();
}
Run Code Online (Sandbox Code Playgroud)
这会将配置缓存到磁盘,因此您的应用初创公司将会很快.当然,当您更改NH映射时,您必须检测并重新加载Fluent配置,否则手动删除缓存文件.
其他一些调整评论:
实际上你不应该在Application_Start()中做SessionFactory.OpenSession().只需在那里创建SessionFactory,并在代码中访问SessionFactory.GetCurrentSession().你的global.asax应该有:
protected void Application_BeginRequest(object sender, EventArgs e)
{
// we open one NH session for every web request,
var nhsession = SessionFactory.OpenSession();
// and bind it to the SessionFactory current session
CurrentSessionContext.Bind(nhsession);
}
protected void Application_EndRequest(object sender, EventArgs e)
{
// close/unbind at EndRequest
if (SessionFactory != null)
{
var nhsession = CurrentSessionContext.Unbind(SessionFactory);
nhsession.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)这将是按请求进行会话的方式.