2011-01-15 15 views
2

私はAsp.NET webform、NHibernateを使用してWebアプリケーションを作成し、SQL Server 2008データベースにアクセスし、StructureMapをIOC Containerとして作成しました。NHibernate StructureMap ASP.NET webform System.OutOfMemoryException

ほとんどのユーザーがそれを使用しているので、すべてがうまくいくようです。ときに、ユーザー数が増加(私たちは10+ユーザーを言うことができます)このエラーでWebアプリケーションがクラッシュ:

System.OutOfMemoryExceptionに

私はレッドゲートアリスイートをダウンロード:パフォーマンスツールは、最大CPU時間がGETALLのためにNHibernateのcreateSessionFactoryであることを述べています要求。

これは私の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を引き起こすものでしょうか? 最高のお礼

+1

あなたは_sessionFactory変数を作成したばかりのファクトリに割り当てないので、毎回 –

+0

が動作するたびに新しいセッションファクトリが作成されます! thx a lot – frabiacca

答えて

2

のSessionFactoryがGETALLメソッドを呼び出すたびに作成されたように見えます。 SessionFactoryの作成はコストのかかる操作です。私は以下の2つのオプションのいずれかに従います

アプリケーションのstartメソッドでSessionFactoryを作成します。これはGlobal.asax.csファイルにあります。その後、他のオプションは、リポジトリ工場やリポジトリプロバイダークラスを持っているだろうので

Global.SessionFactory.OpenSession 

としていずれかの方法からアクセスすることができ、グローバルasaxクラスのSessionFactoryのための静的パブリックプロパティを公開します。これには、接続文字列を取り込むコンストラクタがあります。コンストラクタのパラメータに基づいてSessionFactoryを構築し、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 
    } 
} 

ようなものになるだろうそして、あなたは今、あなたはあなたがリポジトリインスタンスを取得することができた使用して、あなたにRepositoryFactoryのインスタンスを与えるためにSMを伝えることができRepositoryFactory

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

のインスタンスを提供するためのStructureMapを設定することができますし、すべてのGetxx呼び出しを行います。

希望すると便利です。

+0

私はそれを試すつもりです。提案ありがとう:) – frabiacca

1

最初に、すべての呼び出しに対して新しいセッションファクトリを作成しています。これは高価な操作です。必要に応じてセッションを作成するアプリケーション用の1つのセッションファクトリが必要です。第二に、すべてのあなたはNHibernateので推奨される作業パターンの単位をフォローしていない:

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

+1

編集:ノーマインド。そうです。彼は決して変数を割り当てません。 –

関連する問題