Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework many-to-many query: navigation property not generated

I have two tables User and UserRole which are they connected using a link table UserInRole

When I generate the entity model, for some reason, the entity UserInRole not getting generated. And as you can see from the picture, Entity Framework understood that there is many-to-many relationship between User and UserRole:

enter image description here

I need to implement the query like this

select ur.Name from [User] as u
inner join UserInRole uir on uir.UserId = u.Id
inner join UserRole ur on ur.Id = uir.UserRoleId
where u.Username = 'magename'

I am using generic repository, if navigation property would exists the query would be looking like this:

from u in repository.AsQueryable<User>()
join uir in repository.AsQueryable<UserInRole>() on u.Id equals uir.UserId
join ur in repository.AsQueryable<UserRole>() on uir.UserId equals ur.Id
where u.Username == userName
select ur.Name

But Entity Framework does not generate UserInRoles navigation property and related UserInRole entity, so the question what should I do in that situation? Should I remove link between UserInRole and UserRole to get entity UserInRole generated in model or there any way to have the query I described above without any changes in database?

UPDATED

so looks i need to do something like that

stirng[] roles = (from u in repository.AsQueryable<User>()
         where u.Username == userName
         select ur.UserRoles.Select(x => x.Name)).ToArray<string>();

getting an error Cannot implicitly convert type 'System.Collections.Generic.List<System.Collections.Generic.IEnumerable<string>>' to 'string[]' any ideas?

like image 318
angularrocks.com Avatar asked May 01 '11 08:05

angularrocks.com


1 Answers

You don't need that link table in your EF model! That's the beauty of EF!!

Check your entity User - it has a UserRoles navigation property - that's the collection of all roles this user is in.

Check out entity UserRole: it has a navigation property Users which has all users that are in this role.

With these two multi-valued navigation properties, you can express any of the queries you might want:

  • find all users for a given role (find the UserRole entity and enumerate its .Users property)
  • find all roles for a given user (find the User and enumerate its .UserRoles)

EF and the EDM sort of "hide" that link table from you - you don't really need it when you're expressing your intent in the conceptual model; those link tables are just a "necessary evil" in relational databases since those databases cannot model m:n relationships in any other way.

Update: so you seem to want to find a list of all the user roles (their names) that a particular user is in - you can express this something like this:

// find the user in your "dbContext" (or via your repository)
var user = _dbContext.Users.FirstOrDefault(u => u.Name == "magename");

// from the list of UserRoles on that user, select the names only
var userRolesNames = user.UserRoles.Select(ur => ur.Name).ToList();
like image 82
marc_s Avatar answered Oct 19 '22 17:10

marc_s