从EF迁移到Fluent NHibernate:内存泄漏,架构

时间:2013-01-30 22:37:26

标签: asp.net-mvc-3 performance nhibernate jquery fluent-nhibernate

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

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

 private static ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
           .Database(MySQLConfiguration.Standard.ConnectionString(
           c => c.FromConnectionStringWithKey("DashboardModels")
       ))
   .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Accounts>())
   .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Notes>())
    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Sales_Forecast>())
     .Mappings(m => m.FluentMappings.AddFromAssemblyOf<ChangeLog>())
      .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Tasks>())

   .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<Accounts>().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<Notes>().AsNoTracking()
                        where notes.Note_ID == id
                        select notes).FirstOrDefault();
             tx.Commit();
            return Json(JsonResponseFactory.SuccessResponse(note), JsonRequestBehavior.DenyGet);
        }
    }

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

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

这就是我个人解决问题的方法(在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<Accounts>().Where(a => a.Deleted == false).AsNoTracking();
            //from customer in session.Query<Accounts>().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<Accounts>())
 .BuildSessionFactory();

 }
}

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

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

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

如果您打算使用Mono,我认为这是一种方式。