从EF转向Fluent NHibernate:内存泄漏,架构

下午好,我正在将一个相当大的项目迁移到Fluent NHibernate,用于单声道。 我已经掌握了大部分关键function,但是我遇到了内存问题。

目前,此代码位于我的两个控制器中。 这似乎不是最优化的。 但我不确定在哪里放这个。

private static ISessionFactory CreateSessionFactory() { return Fluently.Configure() .Database(MySQLConfiguration.Standard.ConnectionString( c => c.FromConnectionStringWithKey("DashboardModels") )) .Mappings(m => m.FluentMappings.AddFromAssemblyOf()) .Mappings(m => m.FluentMappings.AddFromAssemblyOf()) .Mappings(m => m.FluentMappings.AddFromAssemblyOf()) .Mappings(m => m.FluentMappings.AddFromAssemblyOf()) .Mappings(m => m.FluentMappings.AddFromAssemblyOf()) .BuildSessionFactory(); } ISessionFactory sessionFactory = CreateSessionFactory(); 

我的大多数数据库调用都是AJAX,有几次调用。 这让我相信我创造了太多会议,而这些会议尚未发布。

  public ActionResult ReadAccounts([DataSourceRequest] DataSourceRequest request) { DataSourceResult result; using (var session = sessionFactory.OpenStatelessSession()) using (var tx = session.BeginTransaction()) { var customers = from customer in session.Query().AsNoTracking() where !customer.Deleted select customer; result = customers.ToDataSourceResult(request); tx.Commit(); } return Json(result, JsonRequestBehavior.AllowGet); } 

考虑我使用StatelessSessions只返回只返回数据的方法。

  public JsonResult GetNoteInfo(int id = 0) { Notes note; using (var session = sessionFactory.OpenStatelessSession()) using (var tx = session.BeginTransaction()) { note = (from notes in session.Query().AsNoTracking() where notes.Note_ID == id select notes).FirstOrDefault(); tx.Commit(); return Json(JsonResponseFactory.SuccessResponse(note), JsonRequestBehavior.DenyGet); } } 

正如我所提到的,这是有效的,但我怎样才能提高内存性能? 大约有5种类似于同时触发的底部方法的方法,所以如果你能提出如何保持记忆不被快速扩展的话,那么之前做过这个的人我会非常感激。 感谢您的时间和快乐的编码!

将为每个请求实例化控制器。 看起来每次创建控制器时都可能调用CreateSessionFactory()。 这是一个非常耗时的调用,通常应该只为应用程序生命周期执行一次。 一种常见的方法是在Global.asax中处理此问题。

至于会话,你已经将它们包装在using语句中,这将确保它们关闭连接等,所以这部分对我来说是正确的。

这就是我亲自解决问题的方法(在DotJoe,Oskar Berggren和其他人的帮助下)

的Global.asax.cs

 public static ISessionFactory SessionFactory = SessionProvider.BuildSessionFactory(); 

调节器

 public ActionResult ReadAccounts([DataSourceRequest] DataSourceRequest request) { DataSourceResult result; using(ISession session = MvcApplication.SessionFactory.OpenSession()) { using (ITransaction tx = session.BeginTransaction()) { var customers = session.Query().Where(a => a.Deleted == false).AsNoTracking(); //from customer in session.Query().AsNoTracking() // where !customer.Deleted // select customer; result = customers.ToDataSourceResult(request); tx.Commit(); } } return Json(result, JsonRequestBehavior.AllowGet); } 

然后我在名为Utilities的文件夹中创建了一个类:

SessionFactory.cs

 public class SessionProvider { public static ISessionFactory BuildSessionFactory() { return Fluently.Configure() .Database(MySQLConfiguration.Standard.ConnectionString( c => c.FromConnectionStringWithKey("DashboardModels") )) .Mappings(m => m.FluentMappings.AddFromAssemblyOf()) .BuildSessionFactory(); } } 

我希望这段代码可以帮助其他需要从EF转换为NHibernate的人。

这使我的内存管理保持在一个非常大的应用程序中,有145个用户,超过450,000kb。 (使用EF从600,000kb下降)certificate了NHibernate的可扩展性。

NHProf也是强烈推荐的。 它有很好的建议,并将为您的具体问题提供资源。

如果你打算使用Mono,这是我认为的方式。