I wrote the following that does work, but want to know if there is any more efficient ways to get all users without any role.
using System.Collections.Generic;
using System.Linq;
using System.Web.Security;
public static IEnumerable<MembershipUser> GetUsersHavingNoRole() {
var allUsers = Membership.GetAllUsers().Cast<MembershipUser>();
foreach (var user in allUsers) {
if (Roles.GetRolesForUser(user.UserName).Length.Equals(0)) {
yield return user;
}
}
}
I'd expect there to usually be more users than roles - so it might make sense to iterate over the roles (return by Roles.GetAllRoles()
), build up a list of users in any of those roles (e.g. by creating a HashSet<string>
and adding the users for each role returned by Roles.GetUsersInRole
), and then finding the difference between that and all the users. So if you're using LINQ, you could use:
var usersInRolesQuery = Roles.GetAllRoles()
.SelectMany(role => Roles.GetUsersInRole(role));
var usersInRoles = new HashSet<string>(usersInRolesQuery);
return Membership.GetAllUsers()
.Cast<MembershipUser>()
.Where(user => !usersInRoles.Contains(user.UserName));
Of course that's still dealing with the same amount of data - but it may mean fewer roundtrips to whatever datastore is involved.
Have you benchmarked the application to find out how expensive your current method is?