2016-03-24 32 views
1

オプション値を選択してフォームを送信すると、繰り返されるデータベース呼び出しを避けるために、非機密オブジェクトをセッションに格納しているドロップダウンメニューがあります。オブジェクトをセッション変数に格納する

private List<Employee> stafflist 
{ 
    get { return Session["stafflist"] as List<Employee>; } 
    set { Session["stafflist"] = new Employee(); } 
} 
private void RemoveStaff() 
{ 
    Session.Remove("stafflist"); 
} 

は、しかし、すべての私の

[HttpPost] 
public ActionResult index (...) 
{ 
    //why can't I get the list of staff like this? 
    ViewBag.staff=stafflist.Where(..).toList(); 

    //is the below still needed? i thought i 
    //have a session variable declare above, 
    //and to avoid 30x repetitive db calls? 
    //also note when i include the below the code runs fine, 
    //however, if i take it out it doesn't. i would like to avoid repetitive db calls 
    stafflist=db.Employee.toList(); 
} 
+0

_ "なぜこのようなスタッフのリストを取得できないのですか?" _ - 正確なエラーを投稿し、あなたの研究を共有してください。また、前もって 'stafflist'メンバに決して割り当てていなければ、それは' null'です... – CodeCaster

+0

@CodeCaster私はstafflist = db.Employee.toList()を使用していないときにのみnull値を取得します。ただし、これを含めると、コードは正常です。私は繰り返しセッションを避けるためにセッションにオブジェクトを格納するプロセスを理解したいと思いますか? – NULL

+0

参照から何かを得るには、最初に何かを保存しなければならないので、少なくとも一度はそれを保存する必要があります。 – CodeCaster

答えて

2

まずでは、データベースを照会するために防ぐべきではありません。正しいキャッシングはハードです。データベースは完全にクエリとキャッシングデータを実行できます。

データベースを迂回し、クライアント側(コントローラ内)を照会することを絶対に確信している場合は、訪問者ごとに少なくとも1回、データベースからスタッフリスト全体を取得する必要があります。

あなたは常にその訪問するユーザーを想定し、このコントローラに最初のGET呼び出しでそれを行うことができます:あなたが実際に再びデータベースクエリを(やりたいPOSTに続いて

[HttpGet] 
public ActionResult Index (...) 
{ 
    var cachedStaff = db.Employee.toList(); 
    Session["stafflist"] = cachedStaff; 
} 

を考えますデータベースは、それが)で良いことだ何をさせるには、セッションからリストを照会することができます

[HttpPost] 
public ActionResult Index (...) 
{ 
    var cachedStaff = Session["stafflist"] as List<Employee>(); 

    // TODO: check cachedStaff for null, for when someone posts after 
    // their session expires or didn't visit the Index page first. 

    var selectedStaff = cachedStaff.Where(..).ToList(); 

    // the rest of your code 
} 
その後

あなたが導入されたプロパティは、少しのコードをクリーンアップする糖衣構文として使用することができます。

private List<Employee> CachedStaff 
{ 
    get { return Session["stafflist"] as List<Employee>; } 
    set { Session["stafflist"] = value; } 
} 

[HttpGet] 
public ActionResult Index (...) 
{ 
    CachedStaff = db.Employee.toList(); 
} 

[HttpPost] 
public ActionResult Index (...) 
{ 
    // TODO: this will throw an ArgumentNullException when 
    // the staff list is not cached, see above. 
    var selectedStaff = CachedStaff.Where(..).ToList(); 

    // the rest of your code 
} 
+0

完璧!多くのありがとう、それは私が逃したインデックスの部分です。 – NULL

+1

@メンク私は、あなたが欠けているより大きな画像は、私の答えではっきりと綴られていると思います。あなたはデータベースに問い合わせることを避けたくありません。各訪問者のために、セッション中のテーブル全体を引っ張ってはいけません。 – CodeCaster

+0

あなたはDBにその仕事をさせると言っていますか?どちらの方が良い?私がキャッシュしているデータは、都市名のように、それほど重要ではありません。ありがとう。 – NULL

0

セッションは、現在のユーザーと現在のセッションで一意です。つまり、ユーザーがブラウザを閉じると、セッション情報が失われます。セッションCookieが削除されると、セッションも失われます。 state managementについて読む

グローバルスタッフリストをすべてのユーザーが利用できるようにするには、別のものを使用する必要があります。その後、最も一般的なケースはCachingです。

関連する問題