Лучший способ получить пользователей, не принадлежащих ни к одной роли?
Я написал следующее, что действительно работает, но хочу знать, есть ли более эффективные способы получить всех пользователей без какой-либо роли.
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;
}
}
}
3 ответа:
Я ожидаю, что обычно пользователей будет больше, чем ролей, поэтому может иметь смысл перебирать роли (возвращаемые
Roles.GetAllRoles()
), создавать список пользователей в любой из этих ролей (например, создаваяHashSet<string>
и добавляя пользователей для каждой роли, возвращаемойRoles.GetUsersInRole
), а затем находить разницу между ними и всеми пользователями. Поэтому, если вы используете LINQ, вы можете использовать: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));
Конечно, это все еще имеет дело с тем же количеством данных - но это может означать меньшее количество обходов, чтобы независимо от того, какое хранилище данных задействовано.
Вы провели сравнительный анализ приложения, чтобы выяснить, насколько дорог ваш текущий метод?
В зависимости от количества пользователей, ролей и отношений между ними и количества раз, когда вам нужна эта информация, она может быть стоит того (было достаточно отказов?) чтобы добавить дополнительный метод к (пользовательскому)поставщику ролей.
Собственный запрос, который требуется в провайдере, может быть намного эффективнее, чем использование LINQ, как вы делаете это сейчас.
Многое зависит от факторов в первой строке этого ответа, но также и от поставщика. Ремонтопригодность также может возникнуть проблема при добавлении запроса, который может не поддерживаться в будущем (следующая версия поставщика)
Если я правильно понял ваш вопрос. Этот код должен помочь!
MembershipUserCollection users = Membership.GetAllUsers(); MembershipUserCollection usersNoRoles = new MembershipUserCollection(); foreach (MembershipUser user in users) { string[] roles = Roles.GetRolesForUser(user.UserName); // if roles empty if (roles.Count() == 0) { // Add User to a List for User with no Roles usersNoRoles.Add(user); } }