2016-09-29 11 views
0

レッツ私はこの宣言辞書持っていると言う表現:クエリC#辞書

public class APIAccessControl 
{ 
    public APIControllerRoute ControllerRoute { get; set; } 
    public APIActionRoute ActionRoute { get; set; } 
    public bool IsAuthorized { get; set; } 

} 

私はチェックしようとしています:キーはroleIdを表し

private static Dictionary<int, List<Models.APIAccessControl>> _APIRights = GetAPIRights(); 

を、値がクラスを表しますユーザーがこのAPIにアクセスする権限を持っている場合。 私の考えでは、辞書を照会し、ロールのAPIAccessControlのすべてのリストを取得し、その後、彼は移動しようとしているAPIActionRouteためにそれらのAPIAccessControlリストを照会することです:

私は私が欲しいの役割のために、これらのリストが含まれている辞書の値を得ました

public static bool CanAccess(int[] roleIDs, APIActionRoute apiActionRoute) 
    { 
      bool canAccess = false; 

      var apiAccessList = _APIRights.Where(x => roleIDs.Contains(x.Key)).Select(x => new { x.Value}).ToList(); 

     //Querying to get all List<Models.APIAccessControl> that has any matchig APIActionRoute 
    } 
+0

DictionaryのValuesプロパティを使用してリストを抽出できます。 –

+0

あなたはキャスティングとクエリを実行するためのサンプルコードを提供できますか、私はエレガントでクリーンな方法でそれを書こうとしています。だから、もしあなたが何か考えを持っているなら、あなたのコードを共有してください。ありがとう – Coding

+0

すべてのActionRoutesを取得してリストに追加するには、apiAccessListのループを使用する必要があります。代わりがあります。あなたができる唯一のことはLinqを使うことです。それが何かを明確にするかどうか私に教えてください –

答えて

1

:匿名クラスへとSelectManyを使用して選択しないことで

var apiAccessList = _APIRights.Where(x => roleIDs.Contains(x.Key)) 
    .SelectMany(x => x.Value).ToList(); 

を、リストにはタイプのModels.APIAccessControl

1

役割を反復処理する方が良いでしょうが、辞書検索を利用するにはまずIDS:が、どのようにリストアップして、このクエリを作成する値の一覧をキャストします。

bool canAccess = false; 
foreach(var roleId in roleIDs) 
{ 
    List<Models.APIAccessControl> controls; 
    if(_APIRights.TryGetValue(roleId, out controls)) 
    { 
     canAccess = controls.Any(control => control.ActionRoute.Equals(apiActionRoute)); 
     if(canAccess) 
      break; 
    } 
} 

あなたはEqualsが実際にあなたが望むことを、比較の種類を行うことを確認する必要があります。デフォルトでは、それは参照の平等であり、値が等しいことを希望する場合はAPIActionRouteの内部にオーバーロードするか、代わりに目的のプロパティの比較を使用する必要があります。

var apiAccessList = 
    _APIRights 
    .Where(x => roleIDs.Contains(x.Key)) 
    .SelectMany(x => x.Value) 
    .ToList(); 

あなたが、その後は以下となります。

完全にLINQのバージョンを使用すると、1つのリストに「リストのリスト」を投影しSelectManyを、したいようですね

List<Models.APIAccessControl> controls; 
bool canAccess = roleIDs.Any(
    r => _APIRights.TryGetValue(r, out controls) 
      && controls.Any(
       control => control.ActionRoute.Equals(apiActionRoute))); 
1

少し厄介ですすべてのAPIAccessControlオブジェクトを1つの大きなリストに入れます。それはもはやroleIDによってグループ化されなくなりました。重複している可能性もありますが、重要ではない場合もあります。あなたはあなたが欲しいリスト与えることを選択句を変更することができます

0

になりますI SelectManyが役立つかもしれないと考えてください。

public static bool CanAccess(int[] roleIDs, APIActionRoute apiActionRoute) 
{ 
    return _APIRights.Where(x => roleIDs.Contains(x.Key)) 
     .SelectMany(x => x.Value) 
     .Any(a => a.ActionRoute == apiActionRoute); 
}