I have default project template of ASP.NET MVC 5 web site and I am trying to list all users with role names (not IDs).
The query is:
db.Users.Include(u => u.Roles).ToList()
Then I want to print the role names with something like:
@string.Join(", ", user.Roles.Select(r => r.RoleId))
The problem is that I can reach only RoleId
, not Role class where Name
and other properties are stored.
I could run another select to get all roles and then use that as a lookup. Or write a join in the query directly? I am not sure how because I do not have access to the table with IdentityUserRole
entities that are binding users and roles together.
The root of the problem seems to be the fact that is Roles collection of IdentityUserRole
(not Role
) which contains only RoleId
and UserId
.
public class IdentityUserRole<TKey> {
public virtual TKey RoleId { get; set; }
public virtual TKey UserId { get; set; }
}
I thought that if one want to do N-to-N relationship in EF they should put directly collection of Roles
and then override OnModelCreating
and specify the relationships. This approach seems to complicate browsing the objects from one to another.
Why they decided to include IdentityUserRole
as extra entity? To be able to add extra data to the relationships? At cost of not being able to navigate from users to roles?
This is how I do it with MVC 5, Identity 2.0 and a custom user and role describe by John Atten
In controller
In ViewModel
And in my View
Thanks to @Callum Linington for his answer. Just Try to make it little bit clear for beginners like me. Here is steps to get a list of users with their roles.
1- Create a view model called "UsersWithRoles" with some properties as shown below :
2- Create a controller called "RolesController", and then add following piece of code in it.
and here is what the RolesController should look like :
3- Add Index page to Roles folder, and add the following code in it.
Here is the result
Thanks.
The way I do it is:
The identity team made two managers:
RoleManager
for sorting out roles (not user roles though) andUserManager
basically for everything authentication wise. There is also aSignInManager
as well but not needed.So
UserManager
finds users, creates users, deletes users, sends emails .... the list goes on.So my
Action
could look like this:To execute raw SQL then you can do something like this:
Create the class that Entity Framework can map to, based on the output of your query:
Pretty simple!
If you alias your SQL return columns:
Then your DTO class can look like this:
Which is obviously a lot cleaner.
I think its bad technique to execute dynamic SQL from your C# application. Below is my method:
Model:
Controller:
View (using ApplicationRole)