Base solution for your next web application

Activities of "tom.ohle"

That worked for us. Our method now looks similar to the following. Thank you.

public async Task<List<ParentItem>> GetParentItems() var parentItems = _parentItemRepository.GetAllIncluding( p => p.ChildItem1, p => p.ChildItem2 ) .AsNoTracking() .ToListAsync(); parentItems.Result.ForEach( p => { p.ChildItem1 = p.ChildItem1.OrderBy(c => c.ChildProperty).ToList(); p.ChildItem2 = p.ChildItem2.OrderBy(c => c.ChildProperty).ToList(); }); return await parentItems; }

Yes, you are right. I wasn't logged in at the time when I checked. My mistake!

Hi @musa.demir,

It seems the issue you created no longer exists.

Hi maliming,

Perhaps something is being lost in translation. To reproduce the steps for our issue, we have created a new test project based off of the 8.7 aspnetzero project. We created a new role and then imported 20,000 users using the excel import on the Administration -> Users page with that role. We then try to delete that role from the Administration -> Roles page. This is where we are getting our issue.

Can you let me know how I can forward you this test project and our excel file of 20,000 test users with our test role to create those users?

Thanks

Hi maliming,

We generated the SQL calls that were produced as a result of the call to DeleteAsync. We manually executed a subset (~1000 statements) against the database using the EntityFrameworkCore ExecuteSqlRaw method just to test out the execution speed as suggested. Performing the sql against 1000 updates took about 23.94 seconds. We also tried encapsulating our DeleteAsync call within a unit of work as suggested with transactions disabled and received this timing with the following code:

output:

***** RoleAppService.DeleteRole ****** DeleteRole Started - 7556.8653 Retreived Users - 7653.065 Selected UserIds - 8804.0222 After DeleteAsync - 9871961.5467

code:

public async Task DeleteRole(EntityDto input) {

        var role = await _roleManager.GetRoleByIdAsync(input.Id);
        var s = Stopwatch.StartNew();
        Debug.WriteLine("***** RoleAppService.DeleteRole ******");
        Debug.WriteLine("DeleteRole Started - " + s.Elapsed.TotalMilliseconds);

        var users = await UserManager.GetUsersInRoleAsync(role.Name);

        Debug.WriteLine("Retreived Users - " + s.Elapsed.TotalMilliseconds);
        var userId = users.Select(x => x.Id).ToList();
        
        Debug.WriteLine("Selected UserIds - " + s.Elapsed.TotalMilliseconds);

        using (var uow = UnitOfWorkManager.Begin(new UnitOfWorkOptions
        {
          Scope = TransactionScopeOption.RequiresNew,
          IsTransactional = false
        }))
        { 
          await _userRoleRepository.DeleteAsync(r => r.RoleId == role.Id && userId.Contains(r.UserId));
       
          uow.Complete();   
        }

        Debug.WriteLine("After DeleteAsync - " + s.Elapsed.TotalMilliseconds);
        CheckErrors(await _roleManager.DeleteAsync(role));
       
    }
    

The DeleteAsync is still taking quite a bit of time. Is there anything else we can do to improve the performance of the DeleteAsync call? We are deleting a role with 20,126 users assigned to it.

Hi maliming,

We tried the suggested code you provided above and added a stopwatch in between the calls. The first 2 statements returned after 3.6 seconds, but the call to DeleteAsync() still does not/has not returned. We are trying to delete over 20,000 records.

Let us know if there is anything you need us to confirm.

Hi maliming,

We tried the approach below but we are still seeing the same performance issue on a brand new ASP.NET Zero 8.7.0 project (ASP.NET Core & Angular).

foreach (var user in users)
{
    await _userRoleRepository.DeleteAsync(r => r.RoleId == role.Id && r.UserId == user.Id);
}

We are currently looking for the root cause of this issue, but in the meantime we would appreciate your thoughts on how we might resolve this issue.

Thanks!

Hi maliming,

I am assuming what you meant is to replace this....

foreach (var user in users)
{
    CheckErrors(await UserManager.RemoveFromRoleAsync(user, role.Name));
}

...with this...

foreach (var user in users)
{
    await _userRoleRepository.DeleteAsync(r => r.RoleId == role.Id && r.UserId == user.Id);
}

If so, does that mean calls to CheckErrors and UserManager.RemoveFromRoleAsync are not important? Do we run the risk of introducing a regression by using the lower level approach?

Hey aaron,

To mitigate this issue, do you see any red flags with setting the expiration to 7 days instead of 1 year?

public class MyProjectWebCoreModule : AbpModule
{
    public override void PreInitialize()
    {
        Configuration.BackgroundJobs.UserTokenExpirationPeriod = TimeSpan.FromDays(7);
    }
}
Showing 1 to 10 of 27 entries