简体   繁体   中英

EF Proxies and complex data structures

The Problem Domain

Say I have an entity that looks something like this ...

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; }
}

Ok now i'm using EF so I can simply do something like ...

var ctx = new MyContext();
var getAll = ctx.HierarchyObjects.AsQueryable();

Now lets say I add permissions to these objects so certain users can only do basic CRUD operations on a subset of these objects I might now do something like ...

getAll = getAll().Where(o => o.Permissions.Any(p => p.Read && UserId == currentUserId));

This returns only the items that the user can access.

Now I want to expose this behind a queryable endpoint, lets say OData.

OData will allow me to write a URL like this ...

~/Api/HierarchyObject?$Expand=Children

... having done that I just broke my security as the EF proxy does not know about my permission rule as the result would be "All objects I have access to and their children" and the real question should have been "all objects I can access expand in to all their children that I have access to".

So my question is

Is there a way to tell EF that when crawling that Children Property it should also apply a where clause ...

o.Children = o.Children.Where(o => o.Permissions.Any(p => p.Read && UserId == currentUserId));

... and apply that rule on all my Heirarchy objects any time it "proxies" one of them?

More details

I found this:

How can I dynamically customize a POCO proxy in EF 4?

All well and good, ssays what i'm trying to do is impossible in EF4 but i'm using EF6 so I figured that Microsoft / someone else perhaps may have foudn a way round this by now allowing a decent way to intercept / override the proxy creation process in some way perhaps using the type IDbSet as the driver for a rule hook that lets you define some proxying rules in some way for relational crawls but I haven't found anything yet!

So it turns out I went the wrong way about this. Instead of proxying the object to prevent relatinship crawling I found I can restrict returned entities by type using EF filters.

There's a bunch of packages for this on Nuget that extend the EF functionality essentially giving a context sensitive "cut of the db" before running any of the business logic code on top of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM