通过实体框架(带有Automapper投影和PredicateBuilder)访问身份声明



我似乎正在努力实现不可能的事情:从我的(实体框架(实体的(计算的(属性中,我试图检查登录用户是否有特定的声明。更确切地说,当尝试在LinqDB查询中使用此属性时,它不起作用。

Linq查询没有什么特别之处:

var query = DbContext.Organizations.Where(x => !x.DeleteDate.HasValue);

数据检索由自动映射器投影触发:

var dto = await query.ProjectToListAsync<MyDto>(Mapper.ConfigurationProvider);

我已在我的组织实体中添加了此属性:

[Computed]
public bool CanCancel => !CancelDate.HasValue 
&& identity.Claims.Any(c => c.Type == permission.ToString());  // identity is of type ClaimsIdentity, permission is an enum from our project

(Computed属性来自DelegateCompiler库,该库允许将委托或方法体反编译为其lambda表示形式。如果用它标记实体的方法,Automapper可以在投影期间在查询中使用它。我们在项目中经常使用这种技术,它非常有用!(

不幸的是,它看起来不像ClaimsIdentity。Claims可以反编译。运行代码会抛出错误

无法创建类型为的常量值"System.Security.Claims.Claim"。仅基元类型或枚举在此上下文中支持类型。

我想这与Claims属性的内部有关:

public virtual IEnumerable<Claim> Claims
{
get
{
for (int i = 0; i < this.m_instanceClaims.Count; ++i)
yield return this.m_instanceClaims[i];
if (this.m_externalClaims != null)
{
for (int j = 0; j < this.m_externalClaims.Count; ++j)
{
if (this.m_externalClaims[j] != null)
{
foreach (Claim claim in this.m_externalClaims[j])
yield return claim;
}
}
}
}
}

但我不知道该怎么解决这个问题。有人有主意吗?

提前感谢!

好吧,我没有找到这个问题的完美解决方案,但我能够通过以下方法解决它:

a( 创建一个检查声明的静态属性:

private static bool CanCancel => identity.HasPermission(AppPermission.CanCancel);

(HasPermission是一种扩展方法,它使用ClaimsIdentity的HasClaim方法来检查标识是否具有给定的权限(

b( 从我计算的属性访问这些属性:

[Computed] 
public bool IsCancelable => !CancelDate.HasValue && CanCancel;

由于此属性不再包含输入变量(例如检查权限(,Linq-to-Entities现在可以将其正确地转换为查询。

相关内容

  • 没有找到相关文章

最新更新