Chris
Chris

Reputation: 3191

How to connect a users table correctly to a Membership table, or should you even do that?

I'm probably going about this the wrong way, please feel free to correct me.

Currently I have a User model called U_USER, it contains fields such as address, receiveNotifications, HasCompanyCar Etc.

These users have roles in a .NET Membership table. When the user logs in via Membership, I get their user record in my database as follows (the username on the Membership table and my own U_USER table will have a match):

        //Gets the current user
        public U_USER CurrentUser()
        {
            return GetUser(HttpContext.Current.User.Identity.Name);
        }

        //Gets user details by username
        public U_USER GetUser(String username)
        {
            return (from u in db.U_USER
                   where u.UserName == username
                   select u).FirstOrDefault();
        }

If I wanted to get a list of all users in, lets say, the "Create" role then I would do this:

allUsers.Where(x => Roles.IsUserInRole(x.UserName, "Create"))

This is a big performance hit as it's doing a lookup for each iteration of a user. This makes me think I'm not going about user management in the correct way. So to answer this question:

How should you properly connect Membership to a users table that in turn is connected to the rest of your data? I'd also accept how to just go about it more efficiently!

Many thanks :)

EDIT :

I've increased performance via the below code. I get the users in the role in one swoop and then filter them.

String[] usersInRole = Roles.GetUsersInRole("CanApprove");
users = users.Where(x => usersInRole.Any(y => y == x.UserName));

But I'm still fairly sure I'm going about this ALL wrong!

Upvotes: 2

Views: 234

Answers (2)

Stuart
Stuart

Reputation: 66882

Not an expert in this, but what my apps typically do is to use a foreign key (with Index) from my own Users table to the Membership Users table using the Guid field with the Membership. This then allows me to do queries using Linq like:

 var query = from myUser in MyUsers
            join aspUser in aspnet_Users on myUser.UserId equals aspUser.UserId
            join usersInRole in aspnet_UsersInRoles on aspUser.UserId equals usersInRole.UserId
            join role in aspnet_Roles on usersInRole.RoleId equals role.RoleId
            where role ...
            select new { ... };

(Or you can use dot-form like myUser.AspUser.Roles.Role to let the ORM generate the joins if you prefer)

For performance, it's good to watch the SQL trace occasionally - make sure you're not making too many SQL round-trips for each logical step in code.

Hope that helps a bit.


Update - in answer to your questions about "should you even do that", I think "yes" but there are other options available - e.g. you can use Profile fields - see Step 6 in this great walkthrough - https://web.archive.org/web/20211020202857/http://www.4guysfromrolla.com/articles/120705-1.aspx

Upvotes: 3

TheRealTy
TheRealTy

Reputation: 2429

We have created EntityFramework entities for all of the AspNet membership tables, this lets us query them like any other entity.

Not sure if it is what your after but may help

Upvotes: 0

Related Questions