2012-01-17 9 views
3

viewstateに値を格納することについて多くの質問がありましたが、良い答えが見つかりませんでした。viewsの代わりにセッション

データベースから大量のデータを取得すると、状況が発生します。それから、私のニーズに応じてデータをフィルタリングして操作します(それで、重度のプロセスです)。次に、結果をカスタムクラスのリストの中に入れます。たとえば、このクラスは人

List<Person> persons = new List<Person>(); 

private void FillPersons() 
{ 
    //Call to webservice 
    persons = ws.GetPersonsList(); 

    //Do all kind of custom filtering 

    //Manipulate the data 

} 

になります言うことができます今、全体FillPersons()方法は、データのかなり少量を返す重い処理です。残念ながら、それはSQLに移動することはできませんし、重さは進行中ですが、それはポイントではありません。

ポイントは、このデータをポストバック間のページで再利用する必要があることです。 今すぐFillPersons()への追加呼び出しを惜しまないために、私はPersonizeクラスをserializeableとしてマークし、viewstateのためにページが1MBのサイズになるという事実以外はviewstateにリストを格納します。私が読んだところによると、それは安全ではなく、ページを重くするようなソースコードを吹き飛ばします(二番目は私が気になるものです)。

私はセッションを残しています。しかし、セッションはポストバックの間だけではなく、それ以降も永続化されます。または、最悪の場合、ユーザーがポストバックを決定する前にセッションが終了します。したがって、セッションの存続期間に最適な期間を見つけることは不可能です。

私の質問は、ポストバックの間に "データセット"を再利用するベストプラクティスですか? あなたはそのような場合に何をしますか?

ありがとうございました。

PS:隠しフィールドなどはオプションではありません。

+0

を使用してリストを取得することができます全体または上のフィルタ処理された、この人のリストアプリケーションです現在ログインしているユーザーですか? – Magnus

+0

最初に取得した後、他の場所、つまりフィルタリングされたデータセットを永続させることはできますか?そうであれば、それを一意のキーとともに保存し、そのキーのみをクライアントに送ることができます。 – GemCer

+0

キャッシュデータを保存した一時データベーステーブルはどうですか? – Holystream

答えて

3

この種のデータはCacheに保存できます。それはアプリケーション全体に適用されるので、それに応じてキーを追加します。

var key = UserID + "_personList"; 
Cache.Add(key, personList, null, 
    DateTime.Now.AddSeconds(60), 
    Cache.NoSlidingExpiration, 
    CacheItemPriority.High, 
    null); 

それがnull、それを補充よりも返す場合は、データがキャッシュにあると仮定ことはできません注(それがフラッシュされている可能性があります)ので、必ずご確認ください。

+0

私は同意します。データベース内のすべてのフィルタリング(それが存在する)が許容されない場合、データのキャッシュは最適なオプションになります。 ViewStateとSessionを悪用すべきではありません。 – NotMe

+0

'Cache'はサーバー上で隠しフィールド(" __VIEWSTATE ")内に保持されない利点があります... –

+0

セッション上のキャッシュの利点は何ですか? – jekcom

2

Viewstateは大きなオブジェクトを格納する良い方法ではありません。あなたのページサイズは大きくなり、すべてのポストバックには時間がかかると述べました。

私はキャッシュを使用することをお勧めします。キャッシュを使用することで、リストはセッションが終了するまでそこに保存されることはありません。そこに保存する時間を設定できます。キャッシングのために、HttpCacheまたはAppFabricまたはMemCachedのようないくつかのdistibutedキャッシングシステムを使用することができます。 This nugetパッケージは、これらのキャッシュシステムの使用に役立ちます。

thisリンクはAppFabricの設定方法を助けます。

私は、より役立ついくつかのコードで編集する必要があります。

https://bitbucket.org/glav/cacheadapter/wiki/Home

var cacheProvider = AppServices.Cache; // will pick cachadapter using web.config (can be Http, Memory, AppFabric or MemCached) 

var data1 = cacheProvider.Get<SomeData>("cache-key", DateTime.Now.AddSeconds(3),() => 
{ 
    // This is the anonymous function which gets called if the data is not in the cache. 
    // This method is executed and whatever is returned, is added to the cache with the 
    // passed in expiry time. 
    Console.WriteLine("... => Adding data to the cache... 1st call"); 
    var someData = new SomeData() { SomeText = "cache example1", SomeNumber = 1 }; 
    return someData; 
}); 
+0

面白い私はこれを見ていきます。ありがとう – jekcom

1

あなたがASP.NET cachingを使用して検討していますか?
あなたのニーズに合ったキーを選択すると、サーバーのメモリにデータが保存されます。ただし、キャッシュはアプリケーション固有のものであり、すべてのユーザーに有効です。
処理するデータが頻繁に変更されない場合、処理アルゴリズムはユーザー固有の設定に依存せず、常に最新のデータを保持することは重要ではありません。

2

キャッシュ以外(マグナスの良いアイデア)、私が考えることができる唯一の他の方法は、データベースサーバーに格納された大量の操作の結果を保持することです。

あなたは、データを取得するのに時間がかかることに言及します。完了したら、ある種類のアクセスキーを使用して意図的に確立されたテーブルに格納します。ブラウザにそのキーを与え、必要なものを引き抜くために使用します。

もちろん、完全なアーキテクチャを知らなくても、ソリューションを提供するのは本当に難しいです。したがって、優先順に:

  1. このユーザーのユニークなキーを使用してデータベースに戻します。
  2. ストアそれリモート・キャッシュ内
  3. ストアそれローカルキャッシュに

いかなる状況の下で、私は、ページ(ビューステート)で、クッキー(とにかく大きすぎる音)、またはセッションに保存します。

+0

良いアイデア、データの非正規化読み取りモデルです。 – Magnus

+0

"このユーザーに固有のキーを使用してデータベースに戻します。"データが頻繁に変更されることがあります。データの有効寿命は、ユーザーがページにとどまる時間とほぼ同じです。リストをシリアライズしてオブジェクトをそのまま保存しない限り、柔軟性を失うと思います。しかし、それが必要となるたびにサーバの性能を打ち消してデシリアライズするのだろうか? – jekcom

+1

@jekcom:必要なときにいつでも新鮮なデータを取得できない場合は、どこに置いても、古い情報を常に処理します。質問は実際にどのくらい古くなっても受け入れられるものである。もしそうでなければ、あなたは絶対にそれを再び引っ張る必要があります。数分(ページ上にある時間)にキャッシュしたら、それをキャッシュします。決してあなたはセッションを使用しません。 – NotMe

1

フィルターを適用したコレクションをディスクにファイルとして保存します。 viewstateに格納できるキーと同じ名前をファイルに付けます。ポストバック時にそのキーを使用してファイルを取得します。ファイルシステムがいっぱいにならないようにするには、2つのフォルダを用意してください。ファイルを保存するフォルダの代替日を指定します。そうすれば、その日に使用されていないフォルダの内容を消去することができます。この方法はパフォーマンスが非常に優れており、フォルダの場所がネットワークパスで識別されている場合は、Webファームで拡張できます。

0

私はpersonlistが共有オブジェクトだと思います。誰もが同じリストを使用していますか?アプリケーションに保存することができます。

Application["PersonList"] =persons; 

persons = (List<"Person">)Application["PersonList"] 

また、Staticクラスに保存することもできます。

public static class PersonList { public static List<"Person"> Get {get;set;} } 

あなたは

PersonList.Get = ws.GetPersonsList(); 

ファイルGlobal.asaxの上のApplication_Startにこのコードを記述する必要がありますし、このコード

persons = PersonList.Get;