我需要根据用户的权限动态过滤特定表格中的数据。例如。 "正常"用户只能看到分配给他的记录,但管理员可以看到所有记录。我使用ninject为每个请求创建数据库上下文,并通过将其他用户信息传递给构造函数来创建上下文。然后我从EntityFramework-Plus扩展中应用动态过滤(EF6):
public MyDbContext(bool isAdmin, string userId) : this()
{
if (!isAdmin)
{
this.Filter<MyTable>(table => table.Where(...));
}
}
此解决方案按预期工作,即调用方法,如:
ctx.MyTable.Where(...)
结果在过滤器中声明了额外的连接。
但是当我使用Find()方法时表现得很奇怪。我正在使用SqlServer探查器来了解幕后发生的事情:
AFAIK这与查询缓存有关,因为在构造函数中添加额外的行似乎可以解决问题:
public MyDbContext(bool isAdmin, string userId) : this()
{
// this "solves" the problem
QueryFilterManager.ClearQueryCache(this);
if (!isAdmin)
{
this.Filter<MyTable>(table => table.Where(...));
}
}
这看起来像是一个很大的矫枉过正,它并没有让我更接近理解这个问题。所以这是我的问题:
这就是我的lambda表达式:
private Func<IQueryable<MyTable>, IQueryable<MyTable>> GetFilter(string userId)
{
return t => t
.Where(c.DataScopes.Any(
x => x.AspNetGroups.Any(
ang => ang.AspNetUsers.Any(
anu => anu.Id == userId))));
}
AspNetGroups是我的自定义表,用于分组用户。数据持久性分配给用户组。