r3plica
r3plica

Reputation: 13387

EntityFramework and IdentityFramework slow when getting users and roles

I am using EntityFramework and for the most part it is fine. I have done some experimenting with Users. When lazy loading is disabled the users are retrieved and displayed pretty fast.

// Disable Lazy Loading
base.Configuration.LazyLoadingEnabled = false;

It takes about 160ms to pull back 26 users. This is fine, but I need the see the Roles and Claims that the user belongs to. I could keep lazy loading disabled and do something like this:

/// <summary>
/// Creates the User response model from the User model
/// </summary>
/// <param name="model">The User model</param>
/// <returns>A User response model</returns>
public UserViewModel Create(User model)
{

    // If we are null, return nothing
    if (model == null)
        return null;

    // Factorise our model
    return new UserViewModel
    {
        Id = model.Id,
        Department = model.Department,
        Disabled = model.Disabled,
        Email = model.Email,
        EmailConfirmed = model.EmailConfirmed,
        FirstName = model.FirstName,
        HasPassword = !string.IsNullOrEmpty(model.PasswordHash),
        HasTroposLogin = model.HasTroposLogin,
        LastName = model.LastName,
        LastLoginDate = model.LastLoginDate,
        UserName = model.UserName,
        UserImage = model.ProfileImageUri,

        DateCreated = model.DateCreated,
        DateModified = model.DateModified ?? DateTime.UtcNow,

        Roles = _userProvider.GetRolesAsync(model.Id).Result,
        Claims = _userProvider.GetClaimsAsync(model.Id).Result.ToList()
    };
}

And in my code I could just do this:

/// <summary>
/// Gets a list of Users
/// </summary>
/// <returns></returns>
public async Task<IList<UserViewModel>> ListAsync(int yield)
{

    // If we have a department get the users for that dept, otherwise get all users
    var users = await Users.ToListAsync();

    // Return our users
    return users.Select(UserFactory.Create).ToList();
}

But doing that increases the loading time to around 5 seconds (for 26 users!) which is just unacceptable. If I enable LazyLoading and remove the factory:

/// <summary>
/// Gets a list of Users
/// </summary>
/// <returns></returns>
public async Task<IList<User>> ListAsync(int yield)
{

    // If we have a department get the users for that dept, otherwise get all users
    var users = await Users.ToListAsync();

    // Return our users
    return users.ToList();
}

It takes about 4.5 seconds but only pulls back role ids and doesn't pull back any claims.

So my question is this:

How can I pull back all the users, roles and claims without it taking circa 5 seconds? Surely I am not the only one that has experienced this?

Upvotes: 0

Views: 126

Answers (1)

CrazyBaran
CrazyBaran

Reputation: 592

You should look for Include method, this method give you posibility to load Related Entities without lazy loading.

var usersWithList = users.include(u => u.Roles).include(u => u.Claims).ToList();

Upvotes: 1

Related Questions