Base solution for your next web application

Activities of "tom.ohle"

Just a general question about the Asp.Net Zero template projects.

Why do you use .Net Standard (netstandard2.0) for the (ProjectName).Application.Shared and (ProjectName).Core.Shared projects instead of .Net Core (netcoreapp3.1)? All the other projects like (ProjectName).Core are using .Net Core (netcoreapp3.1). We were thinking about updating these to .Net Core but didn't know if there was a reason we shouldn't.

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; }

We are using the ASP.NET Zero template version 9.0.1. How do you go about sorting child entites when they are retrieved using the GetAllIncluding method? According to the Microsoft documentation we should be able to do the following. https://docs.microsoft.com/en-us/ef/core/querying/related-data#filtered-include.

return await _entityRepository.GetAllIncluding( e => e.childEntities .OrderBy( ce => ce.childProperty) ) .ToListAsync();

I would normally submit this as a pull request, but alas...

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.

I have an AbpODataEntityController and I want to add a custom FilterBcEnableQueryAttribute on the Get class. However, I cannot figure out how to implement dependency injection in the FilterBcEnableQueryAttribute class. How could I get an instantiated version of my IPermissionPolicyManager class, for example?

` public class WipsSearchController : AbpODataEntityController<WipSearch, long>, ITransientDependency {

    public WipsSearchController(IRepository<WipSearch, long> repository) : base(repository) 
    {
    }
    
    
    [DontWrapResult]
    //compile error here since no empty constructor; if I add empty constructor, the dependencies are not initialized
    [FilterBcEnableQuery]
    [AbpMvcAuthorize(AppPermissions.BusinessRule_Wips_View)] 
    public IQueryable<WipSearch> Get()
    {
        return base.Get();
    }
}

public class FilterBcEnableQueryAttribute : EnableQueryAttribute, ITransientDependency
{
    private readonly IPermissionPolicyManager _permissionPolicyManager;
    private readonly IWipBcPolicyHandler _wipBcPolicyHandler;


    public FilterBcEnableQueryAttribute(IPermissionPolicyManager permissionPolicyManager,
        IWipBcPolicyHandler wipBcPolicyHandler)
    {           
        _permissionPolicyManager = permissionPolicyManager;
        _wipBcPolicyHandler = wipBcPolicyHandler;
    }

    public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var args = context.HttpContext.ODataFeature();
        var bcOrgIds = new List<long>();
        var userPolicies = _permissionPolicyManager.GetUserPermissionPolicies(AppPermissions.BusinessRule_Wips_View);
        var bcUserPolicies = userPolicies.Where(p => p.PolicyName == AppPolicies.Wips_Bcs).ToList();
        
        var request = context.HttpContext.Request;
        var url = context.HttpContext.Request.GetEncodedUrl();
        if (url.IndexOf("$filter") == -1)
        {
            context.Result = new RedirectResult("http://localhost:22742/odata/wipssearch?$filter=BcNumber%20eq%20'1609'");
        }
        
        base.OnActionExecuting(context);
    }

} }`

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.

Showing 1 to 10 of 50 entries