加速 NHibernate SessionFactory 创建过程

Speed up the NHibernate SessionFactory create process

我正在使用 Asp .Net MVC 和 NHibernate 作为 ORM 工具开发一个网站。 我只是使用一些原则实现了一些模式。 它们是 IoC、Service-Repository 和 UoW。

我在缓存方面使用了 NHibernate 的几乎所有功能,如下所示

到目前为止一切都很好,我可以在 1 秒内加载整个网站,总共大小将近 7.5 MB(主要是来自 Azure 存储的图像),而无需 Asp .Net MVC 的输出缓存基础设施,但当我第二次加载该网站时会发生此操作。

最大的问题是 NHibernate SessionFactory 在首次加载时将项目的正常运行时间增加了将近 15 秒,这是不可接受的。

我有 25 个实体,所以它们实际上是映射,为什么第一次要花这么多时间?

这是我的 Nhibernate 配置

public static ISessionFactory GetSessionFactory()
{
        return Fluently.Configure()
       .Database(MsSqlConfiguration.MsSql2012
       .Raw("connection.isolation", "ReadCommitted")
       .ConnectionString("connectionString")
       .Mappings(gX => gX.FluentMappings.AddFromAssemblyOf<MyEntity>())
       .Cache(gX => gX.ProviderClass<SysCacheProvider>()
       .UseSecondLevelCache()
       .UseQueryCache())
       .BuildSessionFactory();
 }

顺便说一下,我对 SessionFactory 的创建过程没有任何问题。唯一的问题是我的项目第一次启动时间。我刚刚解决了很多有关缓存策略的问题,但无法弄清楚 SessionFactory。

对此有什么想法或建议吗? 谢谢

一些可能对您有帮助的评论。

  1. 您可以在构建会话工厂后对其进行序列化。看到这个 blog post for more info。或 Google serialise sessionfactory nhibernate 因为有很多文章

  2. 如果这是一个网站,那么我会始终确保它启动并且永远不会因不活动而停止。一种方法是在 uptime robot 上注册一个免费帐户,该帐户每 5 分钟对您的站点执行一次 ping 操作(请求 headers),从而使它保持活动状态。但是,在任何更改架构的部署中,您的启动时间仍然会很慢。

下面是我序列化 NHibernate SessionFactory 的方法,您应该可以根据上面的博客 post 对其进行调整以满足您的需要。我见过有人使用#Debug 指令或文件创建时间来查看文件是否需要重新生成。

  private static ISessionFactory SetUpNhibernate()
    {

        var file = HttpContext.Current.Server.MapPath("~/App_Data/cfg-serialised.xml");
        IFormatter serializer = new BinaryFormatter();
        var cfg = new Configuration();

        if (File.Exists(file))
        {
            using (var stream = File.OpenRead(file))
            {
                cfg = serializer.Deserialize(stream) as Configuration;
            }
        }
        else
        {
            var mapper = new ModelMapper();
            mapper.AddMappings(typeof(CmsMeta).Assembly.GetTypes());
            var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();
            cfg.Configure();
            cfg.AddDeserializedMapping(mapping, "Domain");
            using (var stream = File.OpenWrite(file))
            {
                serializer.Serialize(stream, cfg);
            }
        }

        return cfg.BuildSessionFactory();
    }