A system I'm helping to refactor uses a dashboard to help manage employees. During development with a small sample, the following code worked reasonably well:
public List<User> GetAllUsersByRoles(String role)
{
var userList = new List<User>();
string[] userNamesFromDB = Roles.GetUsersInRole(role);
foreach(string username in userNamesFromDB)
{
MembershipUser userFromDB = Membership.GetUser(username);
User user = ConvertUserFromDatabase(userFromDB);
user.Roles = Roles.GetRolesForUser(username);
userList.Add(user);
}
return userList;
}
As you can see, this iterative loop is making multiple trips to the database for every single user, and isn't scaling.
I'm hoping to use Linq with the Entity Framework to grab a number of users at the same time. This is easing the pain of all the joins, but it's still making a trip to the database for every user.
How can I transform this code to grab all users at the same time? I've used SelectMany
in the past with success to solve this problem, but it doesn't seem to be translating here.
public List<User> GetAllUsersByRoleForDashboard(String role)
{
List<User> userList = new List<User>();
string[] userNamesFromDB = Roles.GetUsersInRole(role);
var users = userNamesFromDB
.SelectMany(user => ctx.aspnet_Users
.Where(x => x.UserName == user)
.Select(user => new User
{
FirstName = ctx.Profile
.FirstOrDefault(x => x.ProfileID == ctx.User
.FirstOrDefault(u => u.UserID == user.UserId).ProfileID).FirstName,
LastName = ctx.Profile
.FirstOrDefault(x => x.ProfileID == ctx.User
.FirstOrDefault(u => u.UserID == user.UserId).ProfileID).LastName,
UserName = user,
IsApproved = ctx.aspnet_Membership
.FirstOrDefault(m => m.UserId == user.UserId).IsApproved,
})).ToList();
return users;
}