使用Lambda表达式

时间:2016-09-29 15:58:14

标签: c# linq dictionary lambda

让'说我有这个声明的词典:

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

如果key表示roleId,则该值表示类:

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

}

我正在尝试检查用户是否有权访问此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
    }

4 个答案:

答案 0 :(得分:1)

最好首先迭代角色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)));

答案 1 :(得分:1)

听起来你想要SelectMany,它会列出一个&#34;列表列表&#34;到一个列表:

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

然后,您将每个APIAccessControl对象放在一个大列表中。但它不再按角色ID分组。它也可能有重复,这可能重要,也可能不重要。

答案 2 :(得分:1)

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

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

如果不选择匿名类并使用SelectMany,则列表将为Models.APIAccessControl

类型

答案 3 :(得分:0)

我认为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);
}