问题域
假设我有一个看起来像这样的实体......
public class HierarchyObject
{
[Key]
public int Id { get; set; }
[ForeignKey("Parent")]
public int ParentId { get; set; }
public virtual HierarchyObject Parent { get; set; }
public virtual ICollection<HierarchyObject> Children { get; set; }
}
好的,现在我正在使用EF,所以我可以简单地做一些像......
var ctx = new MyContext();
var getAll = ctx.HierarchyObjects.AsQueryable();
现在假设我添加了对这些对象的权限,因此某些用户只能对这些对象的子集执行基本的CRUD操作,我现在可以执行这样的操作......
getAll = getAll().Where(o => o.Permissions.Any(p => p.Read && UserId == currentUserId));
这只返回用户可以访问的项目。
现在我想在可查询端点后面公开它,比方说OData。
OData将允许我写这样的URL ......
〜/原料药/ HierarchyObject?$展开=儿童
...这样做我刚刚破坏了我的安全性,因为EF代理不知道我的权限规则,因为结果将是“我有权访问的所有对象及其子女”,真正的问题应该是“所有我可以访问的对象扩展到我有权访问的所有子节点。“
所以我的问题是
有没有办法告诉EF,当抓取那个Children属性时,它也应该应用where子句......
o.Children = o.Children.Where(o => o.Permissions.Any(p => p.Read && UserId == currentUserId));
...并且只要它“代理”其中一个对象,就在我的所有Heirarchy对象上应用该规则?
更多详情
我发现了这个:
How can I dynamically customize a POCO proxy in EF 4?
一切都很好,ssays我想要做的事情在EF4中是不可能的,但我使用的是EF6,所以我认为微软/其他人也许可能已经有了一个方法,现在允许一个体面的方式来拦截/以某种方式覆盖代理创建过程,可能使用类型IDbSet作为规则挂钩的驱动程序,允许您以某种方式为关系爬网定义一些代理规则但我还没有找到任何东西!
答案 0 :(得分:1)
事实证明我对此采取了错误的方式。 我发现可以使用EF过滤器按类型限制返回的实体,而不是代理对象以防止关联抓取。
在Nuget上有一堆软件包可以扩展EF功能,从而在运行任何业务逻辑代码之前提供上下文敏感的“数据库剪切”。