2011-11-10 11 views
1

以下の方法では、管理者権限を選択し、キャッシュされたDataTableからboolを返します。これはLINQでよりうまくいくのでしょうか?

なぜテストしないのかと聞かれるかもしれません。まあ、による知識の不足のために、私はそれがmyRole変数が定義されていないとして、あなたが記載されたコードが、完全ではないのLINQ

DataRow[] result = PrivilegeMap.Select("privilegeActionId=" + (int)actionId); 
      bool moderatorHasIt = Convert.ToBoolean(result[0]["moderatorHasIt"]); 
      bool adminHasIt = Convert.ToBoolean(result[0]["adminHasIt"]);           
      if (myRole == User.Role.Admin) 
      { 
       return Convert.ToBoolean(adminHasIt); 
      } 
      if (myRole == User.Role.Moderator) 
      { 
       return Convert.ToBoolean(moderatorHasIt); 
      } 
      else 
      { 
       return false; 
      } 
+0

DataTableが 'Select'クエリに基づいてインデックスを管理していたので、私の答えは削除されました。 – Ani

答えて

1

データテーブルがクエリ文字列を解析する必要がないため、LINQを使用する方が高速ですが、データ表現を変更することで最大の利点を得ることができます。

興味のある特典を表すIDictionary<int, bool>を作成し、actionIdと入力してください。ルックアップが必要な場合は、dict[actionIdを返すことができます。

時期尚早最適化:あなたのプログラムをテストしましたが、このコードは処理時間のかなりの部分を占めていることが判明しましたか?

+0

ありがとうございます。それは少数のユーザーによってのみ呼び出されることはありません。私はちょうどlinqが大きな違いを生むかどうかを知りたかった。 – nLL

+0

@nLL:あなたの時間は他の場所で使うのが一番です。 :-) – StriplingWarrior

+0

データベースはLinq、Datatable、または手作業のSQLから来ているかどうかを解析する必要があります。 –

1

に書き込むことはできません。

これを念頭に置いて、switch文で記述し、問題として特定されるまで移動することをお勧めします。プラス(私の意見では)読みやすくなります。

2

とすることができる。

のは、次のことを想定してみましょう:

  1. サイズを開始するとのバランス、基礎となる表の周波数と更新頻度はそれがにそれをすべてをロードすることに全部を交換しても意味がないようなものである読みますメモリだけでそれを繰り返し見ている。

  2. 各IDに一致する行は1つだけです。

  3. 行には他の興味深いフィールドがたくさんありますが、ここでは気にしません。それはちょうど違うvar result = (from p in PrivilegeMap where p.PrivilegeActionId == actionID select new{p.ModeratorHasIt, p.AdminHasIt}).First()と言えばvar result = PrivilegeMap.Where(p => p.PrivilegeActionId == actionID).First(p => new{p.ModeratorHasIt, p.AdminHasIt})も書き込むことができます

    var result = PrivilegeMap.Where(p => p.PrivilegeActionId == actionID).Select(p => new{p.ModeratorHasIt, p.AdminHasIt}).First() 
    if (myRole == User.Role.Admin) 
    { 
        return result.AdminHasIt; 
    } 
    if (myRole == User.Role.Moderator) 
    { 
        return result.ModeratorHasIt; 
    } 
    else 
    { 
        return false; 
    } 
    

    (:私たちはLinq2SQL Table<Privileges>でPrivilegeMapを交換した場合

はその後、同等のLINQのコードのようなものになるだろう同じLINQ操作の構文)。

actionIDあなたのコードは、の線に沿ってSQLに変換されます2 あるとしましょう:

:上記privilegeActionId = 2

LINQのがになっられる特権FROM

SELECT * SELECT TOP 1 adminHasIt、moderatorHasIt FROM特権WHERE privilegeActionId

これがたくさんの列を持つ表であったかどうか、および/または一致する行が複数ある場合は、これはずっと効率的です。

(PrivilegeMapが列挙可能でしたが照会できない場合は、すべてがロードされスキャンされたため、まったく効率が悪い操作に変わります)。一方、そのSQLを生成するコードは複雑になる可能性があり、権限エンティティオブジェクトを設定する際にはいくつかの作業が必要です。これが一回限りの操作であれば、開発者効率やランタイム効率の面ではそれほど価値がないかもしれませんが、そうでなければ両方に利益をもたらす可能性があります。

ただし、両方のケースで不必要にクエリを実行しています。私は実際に地雷を交換したい:私たちはどんなデータベースの状態myRoleの他の値にfalseを保証しませんしているので、ちょうどadminHasIt、ちょうどmoderatorHasIt、またはのためのいずれかのクエリはまったく照会しません

if (myRole == User.Role.Admin) { return PrivilegeMap.Where(p => p.PrivilegeActionId == actionID).Select(p => p.AdminHasIt).First(); } if (myRole == User.Role.Moderator) { return PrivilegeMap.Where(p => p.PrivilegeActionId == actionID).Select(p => p.ModeratorHasIt); } else { return false; } 

同様に、あなたがして非常に簡単な改善を得る:我々はない、おそらく、それを使用するだけで、我々は気にフィールドを変換し、行うことができない場合

if(myRole != User.Role.Admin && myRole != User.Role.Moderator) 
    return false; 
DataRow[] result = PrivilegeMap.Select("privilegeActionId=" + (int)actionId); 
if (myRole == User.Role.Admin) 
{ 
    return Convert.ToBoolean(result[0]["adminHasIt"]); 
} 
if (myRole == User.Role.Moderator) 
{ 
    return Convert.ToBoolean(result[0]["moderatorHasIt"]); 
} 

をここでは、最初の完全データベースクエリを避けます続いてboolをboolに変換します。実際にどのようなデータが使用されているかについてのこのようなローカルな考え方ははるかに簡単であり、そのような節約の大部分は小さく、大きなもの(潜在的に可能性があります)、複雑なトレードオフではなく習慣の問題です。

+0

ありがとうございました。今はもっとはっきりしています。 – nLL

+0

あなたの質問はテーブルがキャッシュされているということだけがわかりましたが、歓迎します。この場合は、@ StriplingWarriorで作成した提案を使用して辞書を使用するほうが速くなります。つまり、キャッシュされたDataTableでもLinq2ObjectsのList でも同じテーブルを照会して、バランスをもう一度変更することができます。後者の場合、linqとあなたのアプローチとの間のパフォーマンスは非常に近いです。 –

+0

+1すばらしい答え。 – StriplingWarrior

関連する問題