Dynamics 365的权限在数据库层面是通过Role表和privilege表N对N关系存储的,N对N关系产生的中间表为roleprivileges。
但是在最近的跟新里面,微软将roleprivileges表隐藏不对用户开放了,所以通过SQL在数据库查询权限和Role实现不了了。
我们还可以通过使用组织服务去获取,具体思路如下:
1. 先遍历所有的role
2. 然后调用RetrieveRolePrivilegesRole方法来拿到每个role的权限
RetrieveRolePrivilegesRole Function (Microsoft.Dynamics.CRM) | Microsoft Docs
3. 找到需要的role
代码:
/// <summary>
/// 获取所有拥有同一个权限的Role集合
/// </summary>
/// <param name="privilegename">权限名称</param>
/// <returns></returns>
public List<string> GetRoles(string privilegename)
{
List<string> list = new List<string>();
Entity Privilege = GetPrivilege(privilegename);
QueryExpression Query = new QueryExpression("role")
{
Distinct = false,
NoLock = true,
ColumnSet = new ColumnSet(true),
Criteria = new FilterExpression()
};
Query.Criteria.AddCondition("parentroleid", ConditionOperator.Null);
EntityCollection Collection = service.RetrieveMultiple(Query);
foreach (var item in Collection.Entities)
{
RolePrivilege[] rolePrivileges = GetRolePrivileges(item.Id);
var obj = rolePrivileges.Where(t => t.PrivilegeId == Privilege.Id).FirstOrDefault();
if (obj != null)
{
list.Add(item["name"].ToString());
Console.WriteLine(item["name"].ToString());
}
}
return list;
}
/// <summary>
/// 获取一个Role下的所有权限
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
public RolePrivilege[] GetRolePrivileges(Guid roleId)
{
RetrieveRolePrivilegesRoleRequest request = new RetrieveRolePrivilegesRoleRequest();
request.RoleId = roleId;
RetrieveRolePrivilegesRoleResponse response = (RetrieveRolePrivilegesRoleResponse)service.Execute(request);
if (response != null && response.Results != null)
{
RolePrivilege[] rolePrivileges = (RolePrivilege[])response.Results["RolePrivileges"];
return rolePrivileges;
}
else
{
throw new Exception($"角色{roleId}错误");
}
}
/// <summary>
/// 获取权限
/// </summary>
/// <param name="name">权限名称</param>
/// <returns></returns>
public Entity GetPrivilege(string name)
{
QueryExpression Query = new QueryExpression("privilege")
{
Distinct = false,
NoLock = true,
ColumnSet = new ColumnSet(true),
Criteria = new FilterExpression()
};
Query.Criteria.AddCondition("name", ConditionOperator.Equal, name);
EntityCollection Collection = service.RetrieveMultiple(Query);
if (Collection.Entities != null && Collection.Entities.Count > 0)
{
return Collection.Entities[0];
}
else
{
throw new Exception($"未查询到{name}权限");
}
}
调用:
List<string> list = GetRoles("prvDeleteIncident");
写在后面:
嫌写代码麻烦,也可以使用XrmToolBox的工具:
Role可以全选。