3

I have a simple model for security where there are:

  • Users
  • Roles
  • Paths

and many to many links between these tables, so a user to roles, and roles to paths. I am trying to write a function so that from a username and a path it will return a bool value based on whether the user has access to that path. How can I do this with the entity framework? I currently have:

var rolesForUser = _entities.Users
         .Include("Roles")
         .Where(u => u.Login.Equals(username))
         .Select(u => u.Roles);

if(rolesForUser.Count() == 0) return false;

var authentications = _entities.WebPaths
         .Where(p => p.Path == path)
         .WhereIn(p => p.Roles, rolesForUser);

return (authentications.Count() > 0);

which uses an extension method WhereIn, however this can only compare on primatives so this doesn't work at the moment. Any suggestions welcome.

1 Answer 1

1

You could probably do it with PredicateBuilder.

Off the top of my head:

var predicate = PredicateBuilder.False<WebPath>();
foreach (var role in from roles in rolesForUser 
                     from r in roles.Role
                     select r)
{
  predicate = predicate.Or (p => p.roles.Any(r => r.Id == role.Id));
}

var authentications = _entities.WebPaths.AsExpandable()
         .Where(p => p.Path == path)
         .Where(predicate);
return (authentications.Count() > 0);
Sign up to request clarification or add additional context in comments.

5 Comments

Hi Craig, just had a go with this and on the line: "predicate = predicate.Or (p => p.roles.Any(r => r.Id == role.Id));" I am not able to access role.Id as role is a System.Data.Objects.DataClasses.EntityCollection object rather than a System.Data.Objects.ObjectQuery<roles>. I guess this is due to how I am selecting within rolesForUser though I'm not sure how to get it to come back as this.
What is the exact type (with parameters) of rolesForUser?
(local variable) IQueryable<System.Data.Objects.DataClasses.EntityCollection<roles>> rolesForUser
Oh, I see. You have a list of lists. I took a stab at flattening it in the edit.
Thanks Craig this looks like it's cracked it. I'm going to have a go at making this simpler if I can but this has answered the question. I had to change the line "from r in roles.Role" to be "from r in roles" but other than that it worked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.