缓存 Fluent NHibernate ISessionFactory

发布于 2024-10-05 16:52:20 字数 230 浏览 3 评论 0原文

我们正在构建一个移动应用程序,并且正在评估 NHibernate + Fluent 与它的配合使用。问题是,我们第一次创建ISessionFactory,花了整整2分钟。尽管表结构非常简单(3个表)。

此后的每次调用都非常快。

我想做的是在应用程序重新启动之间缓存 ISessionFactory,或者以某种方式首先加速它的创建。

关于是否可以缓存有什么想法吗?从我所有的阅读来看,没有太多的加速。

We're building a mobile application, and we're evaluating NHibernate + Fluent for use with it. The problem is, the first time we create the ISessionFactory, it takes a full 2 minutes. even though the table structure is very simple (3 tables).

each call after that is extremely fast.

what i'd like to do is either cache the ISessionFactory between application restarts, or somehow speed up the creation of it in the first place.

Any ideas on if it's possible to cache? from all my reading, there's not much speeding it up.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

妥活 2024-10-12 16:52:20

您可以序列化并保存配置并在第二次加载该配置,以减少创建所需的时间。不过,如果您进行更改,您需要清除旧配置并序列化新版本,否则您将加载旧配置。

我不记得执行此操作的代码,将尝试挖掘一个示例。

编辑:
http://vimeo.com/16225792

在 Ayende 的这段视频中,大约 24 分钟讨论了配置序列化。

You can serialize and save the configuration and load that up the second time around to reduce the time it takes to create. Tho if you make changes you need to blow away the old config and serialize a new version, otherwise you will be loading up old configuration.

I can't remember the code to do this tho, will try dig up an example.

Edit:
http://vimeo.com/16225792

In this video at about 24 minutes in Ayende discusses Configuration Serialization.

叫思念不要吵 2024-10-12 16:52:20

将 ISessionFactory 定义为静态变量(与 VB 共享)并在应用程序启动时仅实例化一次,这就是 Web 应用程序解决此问题的方法。
我意识到这可能会给具有内存效率要求的移动应用程序带来挑战,但根据您使用的移动平台,应用程序的生命周期可能不会像人们担心的那么短......

    public class NHHelper {
        private static string _connectionString;
        private static ISessionFactory _sessionFactory;

        private static ISessionFactory SessionFactory {
            get {
                if (_sessionFactory == null) {
                            _sessionFactory = Fluently.Configure()
                                .Database(MsSqlConfiguration.MsSql2008.ShowSql()
                                    .ConnectionString(p => p.Is(_connectionString)))
                                .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetAssembly(typeof(NHHelper))))
                                .BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }

// this is called once upon application startup...
        public static void WarmUpSessionFactory(string connectionString) {
            _connectionString = connectionString;
            var factory = SessionFactory;
        }
// this is what you call to get a session for normal usage
        public static ISession OpenSession() {
            return SessionFactory.OpenSession();
        }
    }

Defining your ISessionFactory as a static variable (Shared for VB) and instantiating it only once upon application startup is how web apps get around this.
I realize this may pose a challenge for a mobile app with memory efficiency demands but depending on the mobile platform you're using the application lifetime may not be as short as one would fear...

    public class NHHelper {
        private static string _connectionString;
        private static ISessionFactory _sessionFactory;

        private static ISessionFactory SessionFactory {
            get {
                if (_sessionFactory == null) {
                            _sessionFactory = Fluently.Configure()
                                .Database(MsSqlConfiguration.MsSql2008.ShowSql()
                                    .ConnectionString(p => p.Is(_connectionString)))
                                .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetAssembly(typeof(NHHelper))))
                                .BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }

// this is called once upon application startup...
        public static void WarmUpSessionFactory(string connectionString) {
            _connectionString = connectionString;
            var factory = SessionFactory;
        }
// this is what you call to get a session for normal usage
        public static ISession OpenSession() {
            return SessionFactory.OpenSession();
        }
    }
_蜘蛛 2024-10-12 16:52:20

当构建 Configuration 和 ISessionFactory 时,NHibernate 正在解析配置和映射以构建其运行时数据结构。 (对于 EF 和 LINQ-to-SQL 也是如此,尽管它隐藏在上下文中。)尽管 2 分钟看起来非常长,但没有什么办法可以消除这种成本。为该代码计时:

        var stopwatch = new Stopwatch();
        stopwatch.Start();
        var cfg = new Configuration();
        cfg.Configure();
        var sessionFactory = cfg.BuildSessionFactory();
        stopwatch.Stop();
        Console.WriteLine("Startup time was " + stopwatch.ElapsedMilliseconds + "ms");

这是一个演示项目,只有几个类和映射,但在没有附加调试器的情况下花费了大约 850 毫秒。连接调试器后,大约需要 2 秒。

您是否尝试过分析您的应用程序以查看它在哪些地方花费了这 2 分钟?

When building the Configuration and ISessionFactory, NHibernate is parsing configuration and mappings to build up its runtime data structures. (This is true of EF and LINQ-to-SQL too, though its hidden within the context.) There is not much that can be done to eliminate this cost, though 2 minutes seems awfully long. Timing this code:

        var stopwatch = new Stopwatch();
        stopwatch.Start();
        var cfg = new Configuration();
        cfg.Configure();
        var sessionFactory = cfg.BuildSessionFactory();
        stopwatch.Stop();
        Console.WriteLine("Startup time was " + stopwatch.ElapsedMilliseconds + "ms");

It's a demo project and only has a few classes and mappings, but it took ~850 ms without the debugger attached. With the debugger attached, it was around 2 seconds.

Have you tried profiling your app to see where it is spending the 2 minutes?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文