【问题标题】:NHibernate StructureMap ASP.NET webform System.OutOfMemoryExceptionNHibernate StructureMap ASP.NET webform System.OutOfMemoryException
【发布时间】:2011-06-09 18:05:26
【问题描述】:

我通过使用 Asp.NET webform、NHibernate 来访问 Sql Server 2008 数据库和 StructureMap 作为 IOC 容器创建了一个 Web 应用程序。

似乎一切正常,因为很少有用户使用它;当用户数量增加时(我们可以说超过 10 个用户)webapp 崩溃并出现此错误:

System.OutOfMemoryException

我下载了 redgate ant 套件:性能工具说最大 cpu 时间在 NHibernate createSessionFactory 中用于 GetAll 请求。

这是我的 NHibernateHelper 对象:

public static NHibernate.ISessionFactory _sessionFactory;
public static NHibernate.ISessionFactory createSessionFactory()
{
try
{
    if (_sessionFactory == null)
    {
    return
        FluentNHibernate.Cfg.Fluently.Configure()
        .Database
        (
        FluentNHibernate
        .Cfg.Db.MsSqlConfiguration.MsSql2008
        .ConnectionString
        (
            c => c
            .Server(ConfigurationManager.DbConnectionValue.Server)
            .Username(ConfigurationManager.DbConnectionValue.User)
            .Password(ConfigurationManager.DbConnectionValue.Password)
            .Database(ConfigurationManager.DbConnectionValue.Database)
        )
        .ProxyFactoryFactory("NHibernate.ByteCode.LinFu.ProxyFactoryFactory,NHibernate.ByteCode.LinFu")
        )
        .Mappings
        (
        m => m.FluentMappings.AddFromAssemblyOf<Repository.IRepositoryBlocco>()
        )

        .BuildSessionFactory();
    }
    else
    return _sessionFactory;
}
catch (Exception ex)
{
    throw ex;
}
}

这是我从 db 读取数据的方式:

public IList<DomainModel.Model.Variabile> GetAll()
{
    try
    {
    var session_factory = NHibernateHelper.createSessionFactory();

    using (var session = session_factory.OpenSession())
    {
        using (var transaction = session.BeginTransaction())
        {
        var query = session.Linq<DomainModel.Model.Variabile>()
            .OrderBy(v => v.ordine);

        return query.ToList();
        }
    }
    }
    catch (Exception ex)
    {
    throw ex;
    }
}

我做错了吗?会不会是引发 OutOfMemoryException 的那个? 最好的问候

【问题讨论】:

  • 你永远不会为刚创建的工厂分配 _sessionFactory 变量,所以它每次都会创建一个新的会话工厂

标签: asp.net nhibernate fluent-nhibernate structuremap


【解决方案1】:

首先,您要为每次调用创建一个新的会话工厂。这是一项昂贵的操作。您的应用程序应该有一个会话工厂,可以根据需要创建会话。其次,您没有遵循 NHibernate 推荐的工作单元模式:

http://nhforge.org/wikis/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.aspx

【讨论】:

    【解决方案2】:

    看起来 SessionFactory 是在每次调用 GetAll 方法时创建的。创建 SessionFactory 是一项昂贵的操作。我会遵循以下两个选项之一

    在 Application 的 start 方法中创建 SessionFactory。这将在 Global.asax.cs 文件中。然后在 Global asax 类中为 SessionFactory 公开一个静态公共属性,可以从任何方法访问它

    Global.SessionFactory.OpenSession
    

    另一种选择是拥有一个 Repository 工厂或一个 Repository Provider 类。这将有一个接受连接字符串的构造函数。它将基于构造函数参数构建 SessionFactory 并创建 Repository 类的实例。 Repository 类将包含您所有的 Getxxx 方法。所以这就像

    public interface IRepositoryFactory
    {
       IRepository GetRepository();
    }
    
    public interface IRepository:IDispose
    {
       IEnumerable<T> Getxxx<T>();
    
    }
    
    public class RepositoryFactory:IRepositoryFactory
    {
        private string _connectionString;
        public RepositoryFactory(string connectionString)
        {
                _connectionString=connectionString;
        }
    
        public IRepository GetRepository()
        {
           //use the connection string and fluently build SessionFactory
           return new Repository(SessionFactory.OpenSession());
        }     
    }
    
    public class Repository:IRepository
    {
       private ISession _session;
       public Repository(ISession session)
       {
            _session=session;
       }
    
       public IEnumerable<T> Getxxx<T>()
       {
           return _session.Query<T>();
       }
    
       public void Dispose()
       {
         //dispose session and any other disposables
       }
    }
    

    您可以配置 StructureMap 以提供 RepositoryFactory 的实例

    For<IRepositoryFactory>.Use<RepositoryFactory>().Ctor<string>.EqualToAppSetting("connStr");
    

    现在您可以告诉 SM 给您一个 RepositoryFactory 实例,您可以使用它获取一个 Repository 实例并进行所有 Getxx 调用。

    希望这会有所帮助!

    【讨论】:

    • 我要测试一下。谢谢你的建议:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多