让'说我有这个声明的词典:
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
}
答案 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);
}