ビジネスオブジェクト(リスト)のスクリーニングに基づいて、

ビジネスオブジェクトベースのスクリーニング

入門

それは時代からAsp.Netにかけ-Aspをされている可能性がありますが、概念はあまりAspで変わっていないが、それは、SQL文を使用して、あまりにも慣れていることでしょう。その結果、我々は、完了するために、データベースへのアプリケーションのロジックのほとんどを持っている.NET Frameworkは、私たちに柔軟で強力なデータ操作機能を提供し忘れてしまうということです。我々はデータをフィルタリングする必要がある場合たとえば、私たちは、リストの代わりに「どこ」節、<T> .FindAll()を考え、私たちはデータをソートする必要がある場合、我々は注文」を考えます「句、代わりのリストが<T> .Sort();我々はリストの代わりに、我々はストアドプロシージャを考えるデータをページングする必要があるときに、<T> .GetRange()。

もちろん、多くの場合、これらのタスクを完了するためのデータベースは、データの場合は特に、大量の非常に効率的であるしましょう。しかし、少量のデータの場合には、すべてのデータを一度削除され、その後、キャッシュのみのため、後のソート、フィルタリング、ページング要求をサーバーにキャッシュし、効率は多くのことを改善します。

単一のメソッドは余地がある、絶対に良いか悪い絶対にありません。ご紹介しますこの記事では、データの量が非常に大きい場合、我々はデータベースをフィルタリングするために、「どこ」句を使用したくない場合があり、その後、再度スクリーニングは、現在のページのデータのみのエントリが表示されることに戻り、同じです。

この記事では、ケースを使用するには、ちょうど同じ質問別の解決策のアイデアがあってもよいです。

あなたはまだSQL文を組み立てていますか?スクリーニングデータの伝統的な方法

データをフィルタリングしますが、最も一般的な操作であるべきであり、我々受注オーダーテーブルNorthwindデータベースの例として。我々はそれが任意の組み合わせで年、月、日によってフィルタリングする必要がある場合、あなたはおそらくそれをどのように行うのでしょうか?私はそれがこのようにすべきだと思います。

  1. 年、月、日を選択するために使用されるページ上の3つのドロップダウンボックスを作成します。
  2. ユーザーがページを訪れた最初の時間は、すべてのデータが表示されます。この時、そこにデータベースへのアクセスがあると、そのような「受注SELECT * FROM」など、すべてのデータ、SQL文を返します。
  3. ユーザーがポストバックを生産、年、月、日中のいずれかを選択します。
  4. ユーザの選択によると、このような「どこ年(受注日)= @Dateと月(受注日)= @Month」として、SQL文を組み立てました。
  5. データベースにSQL文を送信すると、データベースは、ユーザーインターフェイスに表示、クエリ結果を返します。
  6. そして、等々。

ユーザーの選択に応じて異なるデータを表示するためには、ユーザの操作は、データベースへのアクセス一度行われるべきであるたびに、私たちは特定の実装を見てするようなもので、上記のモードで見ることができます。

SQL文の組み立て典型的な実装

以下に示すように、まず、3ページのDropDownListコントロール、GridViewの、およびObjectDataSourceコントロール上に配置されたページ(SqlApproach.aspx)を作成します。

(Order.csを設置)App_CodeフォルダーにOrdersテーブルに基づいてビジネス・オブジェクトを作成するため。

publicクラス受注
{
    プライベートint型の注文ID。//订单同上
    プライベート文字列はcustomerId。//用户同上
    民間のDateTime orderDateで。//下单日期
    プライベート文字列の国。//国家

    公共int型のOrderIdで{
       取得{注文IDを返します。}
       集合{注文ID =値。}
    }

    パブリック文字列は、CustomerIdの
    {
       取得{得意先返します。}
       集合{はcustomerId =値。}
    }

    公共のDateTime受注日は
    {
       取得{orderDateでを返します。}
       集合{orderDateで=値。}
    }

    パブリック文字列国
    {
       {リターンの国を取得します。}
       集合{国=値。}
    }
}

セット(リスト、または回線セットを呼び出す)データのために、私たちは店に一覧<注文>を使用します。次に、データベースからリストを作成する、結果セットを返すために、ディレクトリにApp_CodeのOrderManager.cs第二のファイルを作成し、一般的に次のようなコードが含まれています。

パブリッククラスOrderManager
{
    //根据SQL语句获取列表对象
    パブリック静的リスト<注文> GetListの(文字列のクエリ)
    {
       リスト<注文>リスト= NULL;
       SqlDataReaderのリーダー=のExecuteReader(クエリ)。

       もし(reader.HasRows){
           リスト=新しいリスト<注文>();
           一方、(reader.Read()){
              list.Add(GetItem関数(リーダ))。
           }
       }

       reader.Close()。

       リストを返します。
    }


    //获取一个SqlDataReaderの对象
    プライベート静的SqlDataReaderののExecuteReader(ストリングクエリ)
    {
       ストリングCONNSTRING = ConfigurationManager.ConnectionStrings [ "NorthwindConnectionString"]のConnectionString。
       SqlConnectionオブジェクトでCONN =新しいSqlConnectionオブジェクト(CONNSTRING)。
       SqlCommandオブジェクトCMD =新しいSqlCommandオブジェクト(クエリ、CONN)。
       conn.Open();
       SqlDataReaderのリーダー= cmd.ExecuteReader(CommandBehavior.CloseConnection)。

       リーダーを返します。
    }

    //从一行获取一个注文对象
    プライベート静的注文GetItem関数(IDataRecordレコード)
    {
       注文アイテム=新規注文()。
       item.OrderId = Convert.ToInt32(レコード[ "注文ID"])。
       item.CustomerId =レコード[ "のCustomerId"]のToString()。
       item.OrderDate = Convert.ToDateTime(レコード[ "受注日"])。
       item.Country =レコード[ "出荷先都道府県"]のToString()。
       返却物;
    }
}

上記のコードはよく理解されている:GetListの()メソッドは、List <オーダー>リストを返し、その後、クエリを受け付けます。GetListの()メソッドの内部で、クエリを作成するのExecuteReader()メソッドのExecuteReader()メソッドを呼び出して、データベースによって返されたデータを読み取るために使用されるクエリに応じて、渡されたSqlDataReaderオブジェクトを返します。各データ線に基づいてOrderオブジェクトを作成するのGetItem()メソッドを呼び出し、文の間。最後に、リスト<注文>リストにOrderオブジェクトを追加し、リストに戻ります。

目に見える、我々は、GetListの(クエリ)メソッドで、我々はのメインコードページファイルSqlFilter.aspxを見てページ上のメソッドを呼び出す必要があります:

<ASP:ObjectDataSourceのID = "objdsOrderList"にrunat = "サーバー" SelectMethod = "GetListの"
     型名= "OrderManager" OnSelecting = "objdsOrderList_Selecting">
     <SelectParameters>
       <ASP:パラメータ名= "クエリ"タイプ= "文字列" />
     < / SelectParameters>
</ ASP:ObjectDataSourceの>

GetListのObjectDataSourceのSelectCommandは、DataSourceID GridViewのために使用されるのObjectDataSource IDとして使用します。

今、私たちは、ポストコードがどのような通常SqlFilter.aspx探し続けて(我々はテキストを設定する際のDropDownListに「すべて」とき、その値「0」):

公共の部分クラスのSqlApproach:System.Web.UI.Page
{
    公共のint年{
       {Convert.ToInt32(ddlYear.SelectedValue)を返します。}
    }

    公共のint月{
       取得{Convert.ToInt32(ddlMonth.SelectedValue)を返します。}
    }

    公共のint型デイ{
       取得{Convert.ToInt32(ddlDay.SelectedValue)を返します。}
    }
   
    //获取查询语句
    パブリック文字列QuerySql
    {
       取得
       {
           int型の年=年。
           int型ヶ月=月。
           int型日=日;

           一覧<文字列> sqlList =新しいリスト<文字列>();
           文字列subSql = String.Emptyを。
          
           (!年= 0)IF
              sqlList.Add(String.Formatの( "年(受注日)= {0}"、年));

           IF(!= 0ヶ月)
              sqlList.Add(String.Formatの(「月(受注日) {0} = "月ザ・));

           IF(= 0日)!
              sqlList.Add(String.Formatの("デイ(受注日)= {0}」、日));

           IF(sqlList.Count> 0)//あなたは、ドロップダウンボックスのいずれかを選択した場合は、SQL文を組み立て
           {
              String []型= sqlList.ToArrayリスト();
              subSql = "どこに(" + String.Join( "と"、リスト)+ ")";
           }
           // SQLステートメントは、組み立て返す
           リターン「のCustomerId、出荷先都道府県、受注日を選択し           subSql +受注から、OrderIdでの」;
       }
    }

    //ページのloadイベント
    をPage_Load(オブジェクト送信者、EventArgsのE)、ボイド保護
    {
        (!IsPostBackプロパティ)IF
        {
            // 12ヶ月の合計; AppendListItem(ddlMonth、12)
            AppendListItem(ddlDay、31); //デフォルトの31日       
        }
    }
   
    //月の変更
    のボイドddlMonth_SelectedIndexChanged保護(SENDERオブジェクト、EventArgsのE){
       gvOrderList.DataBind();
    }

    //年間の変化
    に保護無効ddlYear_SelectedIndexChanged(SENDERオブジェクト、EventArgsのE){
       gvOrderList.DataBindは();
    }

    日変更//
    保護しますボイドddlDay_SelectedIndexChanged(オブジェクト送信者、のEventArgs電子 ){
       gvOrderList.DataBind();
    }

    //リスト項目を追加
    、ボイドAppendListItem(ListControlリスト、エンドint)を保護して、{
       (私は= int型1。;私は=終了<;私は++)について{
           list.Items.Add(新新のListItem(I. ToStringメソッド()));
       }
    }

    //各リストポストバックgvOrderList.DataBind()を呼び出します、そして、ここでトリガ
//今度は、データベースからデータを返す、OrderManager.GetList(クエリ)メソッドを呼び出します。
    保護されたボイドobjdsOrderList_Selecting(オブジェクト送信者、ObjectDataSourceSelectingEventArgs E){
       e.InputParameters [ "クエリ"] = querySQL;
    }
}

このコードは、年、月3つのプロパティは、年に取得した、日、月の値、DropDownListコントロールの日を使用しています。3つのリストの状態に応じてアセンブリを実行するSQL文は、メイン論理QuerySqlプロパティに含まれています。最後に、ObjectDataSourceののSelectingイベントで配送方法QuerySqlでは、オブジェクトのリストを取得し、ページに表示されます。

:コードを簡単に作るために、私は類似した1997年2月30日、このような特別な日に対処する必要はありません。クエリが唯一の空のリストを返すよう、これは単なるサンプルプログラムであるため、でもこの日付で、プログラムは、ミスをしていない、私たちはまた、受け入れることができると思います。

ビジネスオブジェクトベースのスクリーニング

SQL文の組み立てに基づく伝統的なスクリーニングを学び、そして今、我々は、オブジェクトベースのスクリーニングでどのように見えるか、そしてどのようにパフォーマンスを向上させるための一種です。

  1. 年、月、日を選択するために使用されるページ上の3つのドロップダウンボックスを作成します。
  2. ユーザーがページを訪れた最初の時間は、すべてのデータが表示されます。この時、そこにデータベースへのアクセスがあると、そのような「受注SELECT * FROM」など、すべてのデータ、SQL文を返します。
  3. 返されるデータは、キャッシュのすべてを(すでに<注文>ビジネスオブジェクトをリストに変換しました)。
  4. キャッシュリスト<注文>スクリーニング、フィルタリングされた結果を返すのユーザの選択は、ページに表示されます。
  5. だから、再び、後続の各ユーザー要求はキャッシュのみのために行きました。

キャッシュポリシー

ここでは、キャッシュを使用するので、キャッシュを議論する必要があります。我々は1がデータキャッシングデータソースコントロールに基づいており、1はOutputCacheで、3つのキャッシュがあることを知って、1はオブジェクトキャッシュSystem.Web.Caching.Cacheクラスに基づいています。3つのキャッシュのうち、OutputCacheおよびデータキャッシュとキャッシュの有効期限ポリシーは、SqlCacheDependencyを適用することができ、SqlCacheDependencyシンプルな発言は、このデータベース(表)にデータベースキャッシュ依存関係にあるときに、データの変更が自動的に有効期限が切れていることで、SqlCacheDependencyは、SQLに分けクライアントアクセスベースのポーリング(ポーリング)プル機構、およびSQL通知(通知)プッシュ機構Server2005に基づいて2つの異なる戦略。SqlCacheDependencyの有効期限ポリシーはSystem.Web.Caching.Cacheを適用する場合、唯一のキャッシュの有効期限ポリシーを変更するには、ファイルベースのアプリケーションや他のアイテムに変更することができます適用することはできません。

:SQLのクライアントアクセスライセンスのポーリング(ポーリング)Asp.Netメカニズムは、時間間隔が固定されているため、時間の処理時間が非常にアクセス時間をミリ秒単位で(ポーリングと呼ばれ、このデータベースへのアクセスの処理を行うことを意味しあなたは)のWeb.Configレーンを設定することができます。訪問上のデータと同じではありませんを検索し、キャッシュはすぐにこのデータを特定の世論調査に依存している有効期限が切れます。通知(通知)は、SQL Server2005メカニズムがAsp.Netはただ自分のことではなく、プロセスを問うためのデータベースを行うには、データベース内のデータが変更された場合は、SQL Server 2005個のプロセスAsp.Net事前通知プロセスと言われ、データは、それが起こった伝えます変更は、その後、Asp.Netキャッシュの有効期限が切れてみましょう。したがっては、SQL Server2005を使用して、通知メカニズムの効率がはるかに高いです。
この記事では、SqlDependencyをオンにする方法に関するものではありません、あなたが参考書を読むことができます。

私は、と私はSQLの道を組み立てるためのあなたは、私がキャッシュを使用するベースのビジネス・オブジェクトをスクリーニングするために感じるかもしれキャッシュを述べたときは、これは、私は今、それぞれのアプリケーションのためのテーブルを列挙され、それらを比較することは公正いないようですパフォーマンスキャッシュは、比較(のSQLServer 2000を使用してSqlDependencyポーリング機構)を作るとき:

キャッシュの名前 SQLベースのスクリーニングアセンブリ ベースのビジネス・オブジェクトをスクリーニング
OutputCache
VaryByParam = "*"
期間= "600"
少ない選択肢際、ドロップダウンボックスに意味のある比較は、バッファ期間中に、データベースにアクセスできません。しかし、ときより多くのオプション、より多くのページはまだあなたの結果をキャッシュされた最初の訪問複数のページ、効果は十分ではありませんデータベースへのアクセス権を持って、キャッシュされます。データベースのデータの変更、キャッシュが期限切れになることはありません。 ビジネス・オブジェクトがキャッシュから読み込まれたので、意味がありません。データベースのデータの変更、キャッシュが期限切れになることはありません。
OutputCache
VaryByParam = "*"
期間= "999999"
SqlDependency = "ノースウィンド:受注"
そして、同じですが、キャッシュの有効期限が切れたときに、データの変更は行います。 データ変更がデータベースに、ページキャッシュは、データを再ロードするように頼まページのキャッシュを有効期限が切れる作るときには、意味がありませんが、データはまだキャッシュからオブジェクトを再ロードされます。その結果、データベースが変更されても、ページが結果が変更されていない表示されます。
ObjectDataSourceの
EnableCaching = "true"を
CacheDuration = "600"
キャッシュの有効時間内に、機能不全のドロップダウンリスト。キャッシュの有効性には、GridViewのにDataBind()メソッドは、(ソースデータが選択イベントをトリガしません)データソースのデータを再読み込みしないので、他の言葉で、データソースがGetListの(クエリ)メソッドを呼び出すことはありませんので、機能不全のリスト。 障害のリストとしてSQL組立方法と効果。
ObjectDataSourceの
EnableCaching = "true"を
CacheDuration = "無限"
SqlDependency = "ノースウィンド:受注"
故障のリストは、同じ効果は、上記のように、唯一の違いは、データベースキャッシュの変化が(最初の失敗の後の最初の訪問、有効なのリストを)有効期限が切れています。 SQLの組立方法のような障害のリスト、。違いは、SqlDependencyも再読み込みデータにデータソース、データキャッシュの有効期限が切れたときに、データベース内のデータの変更、ために失敗ですが、データはまだキャッシュから来ています。
Catch
Insert("fullList", List<Order>)
基本不可实施(对每次返回结果进行缓存,效果基本等同于全部返回,且非常麻烦) 本文对象即是应用此方法缓存。

很明显,本文使用的方法的问题就是:当数据库数据变动时,缓存不能够即时过期。解决方法有两种:一个是使用Cache.Insert()的重载方法,设置缓存的自动过期时间(时间设的短了缓存优势不明显,时间设的长了数据变化不能即时反应);还有一个是在对数据库进行增删改时使用Cache.Remove()手动移除缓存(比较麻烦容易遗漏)。

本文不是讲述如何使用缓存的,上面是让大家了解使用缓存都会发生哪些可能,只要知道使用Cache.Insert(key,value)方法可以添加缓存就可以了。最后再说一下当我们使用Cache.Insert(key,value)插入缓存时,虽然没有设置过期时间,但是当服务器内存空间不足的时候,依然会将缓存移除。

对业务对象进行筛选

基于业务对象筛选其实就是基于List<Order>进行筛选(当然你的业务对象也可能不是List<Order>),思路似乎很简单,我们先通过一个重载的GetList()方法获取全部列表,在这个GetList()方法中应用缓存。然后遍历业务对象,选出它符合条件的项目,然后将符合条件的项目加入到新列表中,最后返回新列表。

// 获取全部列表
public static List<Order> GetList() {
    List<Order> list = HttpContext.Current.Cache["fullList"] as List<Order>;

    if (list == null) {
       list = GetList("Select OrderId, CustomerId, ShipCountry, OrderDate From Orders");
       // 添加缓存,永不过期(可以在删除、更新操作时手动让缓存过期)
       HttpContext.Current.Cache.Insert("fullList", list);
    }

    return list;
}

// 根据一个全部项目的列表,以及年、月、日对列表进行筛选
public static List<Order> GetList(List<Order> fullList, int year, int month, int day)
{
    List<Order> list = null;
    bool canAdd;      // 标记变量,说明当前项目是否符合添加的条件

    if (fullList != null)
    {
       list = new List<Order>();

       foreach (Order item in fullList)
       {
           canAdd = true;

           if (year != 0 && year != item.Date.Year)
              canAdd = false;

           if (month != 0 && month != item.Date.Month)
              canAdd = false;

           if (day != 0 && day != item.Date.Day)
              canAdd = false;

           if (canAdd == true)      // 如果全部条件满足,那么加入列表
              list.Add(item);
       }
    }

    return list;
}

上面无参数的GetList()方法在没有缓存的情况下调用GetList(query)方法,返回全部列表,然后加入缓存;有缓存的情况下直接使用缓存中的数据。在GetList(fullList, year, month, day)方法中,根据 年、月、日 对传递进去的列表(全部列表)进行了筛选。

使用List<T>.FindAll(Predicate<T> match)进行筛选

上面的方法虽然可以完成任务,但是不够好,为什么呢?

  1. 我们将筛选的条件(年、月、日)紧耦合到了GetList()方法中,如果日后想添加对其他列,比如国家的筛选,那么我们的方法签名就需要改变(添加国家),而所有调用GetList()方法的地方都需要修改。
  2. 代码没有重用,针对年、月、日来进行筛选是一项很常见的任务,我们应该把这部分封装起来,以后对其他的业务对象进行筛选时,使这些代码可以重用。

实际上,这些问题.Net Framework已经为我们想到了,并在List<T>上提供了一个FindAll(Predicate<T> match)方法来进行筛选的工作,而Predicate<T>类型的参数,封装了筛选的规则。Predicate<T>是一个泛型委托,这意味着match参数是一个返回bool类型的方法,在FindAll()内部,会调用我们传递进去的这个方法。

public delegate bool Predicate<T>(T obj);

NOTE:我看到过这样的一句话,是问Librariy和Framework的区别是什么?回答是:我们调用Librariy的方法,但是Framework调用我们的方法(当然我们也会调用Framework)。可见Framework是一个扩展性和弹性很高的东西,在很多地方我们可以将自己的代码融入到Framework中去。

现在我们来看下如何定义满足 Predicate<T>委托的方法。如果我们将方法写在OrderManager类的内部,那么似乎可以这样写:

// 进行数据筛选的主要逻辑
public bool MatchRule(Order item)
{
    if (year != 0 && year != item.Date.Year)
       return false;

    if (month != 0 && month != item.Date.Month)
       return false;

    if (day != 0 && day != item.Date.Day)
       return false;

    return true;
}

可实际上,你发现没有地方来传递year, month, day参数,因为Predicate<T>(T obj)要求只接受一个参数,在这里是Order类型的item。所以,实际上我们要对这个方法进行一个简单的封装,让我们可以传递year, month, day参数进去。在进行封装之前,我们应该考虑:对于年、月、日的筛选是很常见的操作,我们要让代码重用。

我们先定义一个接口,这个接口仅要求返回一个DateTime类型的属性Date,对于所有实现了这个接口的类,都应该可以使用我们的筛选方法(一个没有日期的对象显然不能按年、月、日筛选)。

public interface IDate
{
    DateTime Date { get; }
}

此时我们的Order类也应该进行修改,让它来实现这个接口,我们只需要它返回orderDate字段就可以了:

public class Order :IDate
{  
    // ... 略
    public DateTime Date
    {
       get { return orderDate; }
    }
}

接下来定义可以用于筛选的类,创建一个DateFilter.cs文件:

// 用于按照年、月、日筛选列表的泛型类,基类
public class DateFilter<T> where T : IDate
{
    private int year;
    private int month;
    private int day;

    public DateFilter(int year, int month, int day)
    {
       this.year = year;
       this.month = month;
       this.day = day;
    }
    // 方便使用的一组构造函数
    public DateFilter(DateTime date) : this(date.Year, date.Month, date.Day) { }
    public DateFilter(int year, int month) : this(year, month, 0) { }
    public DateFilter(int year) : this(year, 0, 0) { }
    public DateFilter() : this(0, 0, 0) { }
   
    // 进行数据筛选的主要逻辑
    public virtual bool MatchRule(T item)
    {
       if (year != 0 && year != item.Date.Year)
           return false;

       if (month != 0 && month != item.Date.Month)
           return false;

       if (day != 0 && day != item.Date.Day)
           return false;

       return true;
    }
}

可以看到,Predicate<T>委托类型的方法MatchRule和前面几乎没有区别,唯一的不同是改成了虚拟方法,以便在子类中覆盖它,以支持对更多列(属性)的筛选。还有值得注意的地方是这个泛型类使用了约束,我们要求类型参数T必须实现IDate接口。

实际上这个类通常用作基类(也可以直接使用,非抽象类),现在来看下如果我们希望可以对Country也进行筛选,应该如何扩展它:

// 可以添加对国家的筛选
public class OrderFilter : DateFilter<Order>
{
    private string country;

    public OrderFilter(int year, int month, int day, string country)
       : base(year, month, day)     // 调用基类构造函数
    {
       this.country = country;
    }

    public override bool MatchRule(Order item)
    {
       // 先获取基类关于日期的对比结果
       bool result = base.MatchRule(item);

       if (result == false)     // 如果日期都不满足,直接返回false
           return false;

       // 继续进行 country 的对比
       if (String.IsNullOrEmpty(country) || string.Compare(item.Country, country, true) == 0)
       {
           return true;     
       } else
       {
           return false;
       }
    }
}

页面实现

我们现在为OrderManager类添加一个新方法,使用我们上面创建的OrderFilter,看看它是什么样的,它仅仅是在fullList上调用了FindAll()方法,传递了我们自定义的DateFilter,然后返回了结果:

// 获取列表对象,使用 filter 作为筛选的条件
public static List<Order> GetList(List<Order> fullList, DateFilter<Order> filter)
{
    List<Order> list = null;
    if (fullList != null)
    {
       list = fullList.FindAll(new Predicate<Order>(filter.MatchRule));
    }
    return list;
}

在ObjFilter.aspx页面上布局与使用拼装SQL几乎没有区别,ObjectDataSource控件的属性有一些变化:

<asp:ObjectDataSource ID="objdsOrderList" runat="server" SelectMethod="GetList"
    TypeName="OrderManager" OnSelecting="objdsOrderList_Selecting">
    <SelectParameters>
       <asp:Parameter Name="fullList" Type="Object" />
       <asp:Parameter Name="filter" Type="Object" />
    </SelectParameters>
</asp:ObjectDataSource>

调用了新的重载了的GetList()方法。然后我们看一下CodeBehind文件上如何进行设置ObjectDataSource的Selecting事件:

// 属性,获取用于筛选的对象
public DateFilter<Order> Filter {
    get {
       DateFilter<Order> filter = new OrderFilter(Year, Month, Day, Country);
       return filter;
    }
}

// 设置参数
protected void objdsOrderList_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
    e.InputParameters["fullList"] = OrderManager.GetList();// 获取全部列表
    e.InputParameters["filter"] = Filter;
}

注意上面Year、Month、Day属性的获取代码以及DropDownList的SelectedIndexChanged事件代码我都省略了以节省篇幅。

事件探查器

OK,现在我们的所有工作都已经完成了,我们来测试一下通过这种方式对数据库依赖的减小。大家可以打开Sql Server2000的事件探查器(Sql Server2005下的Sql Server Profiler)。选择“文件” --> “新建” --> “跟踪” --> 进行登录。之后应该如下图所示:

选择“事件”选项卡,之后如下图所示:

从右侧“选定的事件”中删除“存储过程”、“安全审查”、“会话”,只保留“T-SQL”,我们只对它进行监视。然后可以看到类似下图,我们对数据库的每次访问都可以在这里看到:

点击上面的“橡皮擦”图标,可以对列表进行清除。然后我们先打开SqlFilter.aspx文件,可以看到我们对列表的每次操作,不管是翻页还是筛选,都会对数据库进行一次查询操作。然后我们点击“橡皮擦”清除掉列表,然后打开ObjFilter.aspx文件,可以看到在对数据库进行了第一次访问以后,后继的动作,无论是进行分页还是筛选操作,都不再对数据库构成依赖。

总结

在这篇文章中,我们主要讨论了如何对业务对象进行筛选。我先提出了很多人的一个思维定势:将操作交给数据库。随后列出了这种操作的典型流程,并在本文中将它称为“基于拼装SQL进行筛选”,然后给出了代码示范。

后半部分,我们详细讨论了基于业务对象进行筛选的方法――将对象缓存在服务器上来对请求提供支持。与前半部分一样,我们先了解了流程,学习了缓存策略,然后进行了代码实现。最后我们使用Sql Server提供的事件探查器对两种情况下对数据库请求的状况进行了跟踪。

感谢阅读,希望这篇文章能给你带来帮助!

转载于:https://www.cnblogs.com/JimmyZhang/archive/2008/03/18/1110708.html

おすすめ

転載: blog.csdn.net/weixin_33695082/article/details/93444019