1

Asp.net WebアプリケーションはLINQ-to-SQLを使用しており(ストアドプロシージャはdbmlファイルにドラッグされてクラスを作成します)、3層アーキテクチャは以下のようなものです。読者がうまく答えられるように、読者に適切なアイデアを与えるための大まかな方法​​を作成しました。

namespace MyDataLayer
{
    public class MyDataAccess
    {
        // global instance of datacontext
        MyDataModelDataContext myDB = new MyDataModelDataContext();     (#1)

        public void GetUserIDByUsername(string sUserName, ref int iUserID)
        {
            int? iUserIDout = 0;
            // this will make call to SP in SQL DB
            myDB.USP_RP_GETUSERIDBYUSERNAME(sUserName, "", ref iUserIDout);
            iUserID = (int)iUserIDout;
        }

        public List<USP_APP_USERDETAILSResult> GetUserDetails(string sUserIDs)
        {
            // this will make call to SP in SQL DB
            return myDB.USP_APP_USERDETAILS(sUserIDs).ToList();
        }
        ...
        ... // several CRUD methods
    }
}

namespace MyBusinessLayer
{
    public class SiteUser
    {
        // global DataAccess instance
        MyDataLayer.MyDataAccess myDA = new MyDataAccess();             (#2)
        public void GetUserIDByUsername(string sUserName, ref int iUserID)
        {
            myDA.GetUserIDByUsername(sUserName, ref iUserID);
        }
        public List<USP_APP_USERDETAILSResult> GetUserDetails(string sUserIDs)
        {
            // this will make call to SP in SQL DB
            return myDA.GetUserDetails(sUserIDs);
        }
        ...
        ... // several CRUD methods
    }
}

namespace MyWebApplication
{
    public class BaseWebPage : System.Web.UI.Page
    {
        // static business layer instance
        public static MyBusinessLayer.SiteUser UserBLInstance = new SiteUser();         (#3)                    
        ...             
    }
}
// Index.aspx.cs code fragment
namespace MyWebApplication
{
    public class Index : BaseWebPage
    {       
        public void PopulateUserDropDown()
        {
            // using static business layer instance declared in BaseWebPage
            List<USP_APP_USERDETAILSResult> listUsers = UserBLInstance.GetUserDetails("1,2,3");

            // do databinding and so on ...
        }
        ...             
    }
}

質問

  • (参照#1)DataAccessにグローバルデータコンテキストを設定することは良いアプローチですか?はい/いいえなぜですか?
  • 提案がリクエストごとにdatacontextを持っている場合、そのためのベストプラクティスは何ですか
  • (参照#2)BusinessLayerにグローバルDataAccessインスタンスを配置することは良いアプローチですか?はい/いいえなぜですか?
  • リクエストごとにDataAccessインスタンスを使用することを提案している場合、そのためのベストプラクティスは何ですか
  • (参照#3)BaseWebPageで宣言された静的ビジネスレイヤーインスタンスは良いアプローチですか?はい/いいえなぜですか?
  • BLインスタンスとDLインスタンスの寿命を一般的に管理するための最良のアプローチ

IISからアプリケーションを再起動すると正常に機能する非常に単純な方法で、本番サーバーで定期的にInvalidCastExceptionが発生します。この問題が発生すると、SQL Management Studioから同じデータベースにアクセスして、同じSPを実行できます。

この問題に関する私たちの主な疑いは、DataContextの管理が不十分であり、DataContextの存続期間の管理についてネット上で多くの記事を読んだことがありますが、現在、さまざまなアプローチについて混乱しています。そのため、同じ状況にある多くの人が問題/回答について明確なアイデアを得ることができるように、質問を詳しく説明しました。

4

2 に答える 2

1

(参照#1)DataAccessにグローバルデータコンテキストを設定することは良いアプローチですか?はい/いいえなぜですか?

はい。

ただし、dataaccessクラス内で手動で作成すると、データコンテキストの存続期間を制御できなくなります。代わりに、データアクセスに挿入されるように、コンストラクターパラメーターにします。

(参照#2)BusinessLayerにグローバルDataAccessインスタンスを配置することは良いアプローチですか?はい/いいえなぜですか?

はい。ただし、1を参照してください。-コンストラクターを介して注入可能にします。

(参照#3)BaseWebPageで宣言された静的ビジネスレイヤーインスタンスは良いアプローチですか?はい/いいえなぜですか?

いいえ。複雑なオブジェクトの静的な状態は避けてください。通常、そのようなオブジェクトは重要な状態になります。そして、これは、並行環境でそのようなオブジェクトを共有すると、多くの厄介な問題が発生する可能性がある場合です。

要約する。

public class DataAccess {
   public DataAccess( DataContext context ) { ... }    
}

public class BusinessLayer {
   public BusinessLayer( DataAccess access ) { ... }    
}

public class MyPage : Page {
 ...

 var ctx = TheDataContext.Current;
 var bl = new BusinessLayer( new DataAccess( ctx ) );  
}

リクエストスコープで共有されるデータコンテキストを使用する場合:

public partial class TheDataContext {

  // Allow the datacontext to be shared in a request-scope
  public static TheDataContext Current {
     get {
         if ( HttpContext.Current.Items["context"] == null )
            HttpContext.Current.Items.Add( "context", new TheDataContext() );

         return (TheDataContext)HttpContext.Current.Items["context"];
     } 
  }
}
于 2012-08-22T14:37:42.350 に答える
0

サンプルでは、​​MyDataLayerの名前は通常Repositoryです。確かに、リポジトリにDataContextインスタンスがあり、それらを外部で使用しようとしないことは良いことです。したがって、リポジトリでのみ、Linq-To-Sqlに依存します。つまり、これらのリポジトリのスタブオブジェクトを作成し、アプリケーションの他の部分を非常に簡単にテストできます。

間違いなく、データコンテキストインスタンスを破棄する必要があります。DataContextに含まれるオブジェクトが多すぎて、それらを存続させ、GCに強制終了させることができません。ご覧のとおり、DataContextesを使用しているときはトランザクションオブジェクトを作成しないので、LinqToSqlは、トランザクションごとにすべてを用意する必要があるという考えに基づいていると思います(もちろん、トランザクションを手動で処理することもできますが、実際にはそうしますか?これをしたいですか?)リポジトリのメソッドにデータコンテキストを配置することは、すべてのORMフレームワークの優れた機能である遅延読み込みを使用できないため、適切なアプローチです。Lazy Loadを使おうとすると、気に入るはずですが、通常、パフォーマンス低下の原因の1つにすぎません。

間違いなく、リクエストの短い時間または同じ時間にDataContextesを使用する必要があります。LongSessionを使用しないでください(複数のHttpリクエストに対してDataContextを保持しようとする場合、それはお尻の痛みであり、必要に応じて他には何もありません)これについて読むには、Hibernateでの長時間実行セッションに関するいくつかの記事を読んでみてください。nHibernateで試しました。自宅ではこれを行わないでください;))。

于 2012-08-22T14:26:28.540 に答える