簡體   English   中英

使用Lambda表達式查詢C#字典

[英]Querying C# Dictionary using Lambda expressions

假設我有這本聲明詞典:

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

其中鍵代表roleId,值代表類:

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

}

我正在嘗試檢查用戶是否有權訪問此api。 我的想法是查詢字典並獲取角色的所有APIAccessControl列表,然后查詢那些他試圖導航的APIActionRoute的那些APIAccessControl列表:

我得到的字典值包含我想要的角色的那些列表,但是如何將值列表轉換為List並進行以下查詢:

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
    }

最好先對角色ID進行迭代以利用“字典”查找的優勢。

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內部重載它,或者改為使用所需屬性的比較。

完整的Linq版本有點混亂

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

聽起來好像您想要SelectMany ,它將一個“列表列表” SelectMany到一個列表中:

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

然后,您將每個APIAccessControl對象都放在一個大列表中。 但是,它將不再按roleID分組。 它也可能有重復項,這可能重要也可能無關緊要。

您可以修改Select子句以提供所需的列表:

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

通過不選擇匿名類並使用SelectMany ,列表的類型Models.APIAccessControl

我認為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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM