简体   繁体   中英

Linq to Entities Getting list of entities by list of variables

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;
}
public List<User> GetAllUsersByRoleForDashboard(String role)
{
    var userNamesFromDB = new HashSet<string>(Roles.GetUsersInRole(role));

    var users = context.aspnet_Users.Where(u => userNamesFromDB.Contains(u.UserName))
    .Select(u=> new User
    {
        // Do your mapping
    }).ToList();

    return users;
}

BTW using HashSet in such queries give you a much better performance

你可以那样做...如果我正确理解你的问题

from u in ctx.aspnet_Users where usernames.Contains(u.UserName) select u;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM