Base solution for your next web application
Open Closed

AbpExceptionFilter with distinct query #4408


User avatar
0
Ricavir created

Hi,

I'm getting an AbpExceptionFilter error with following query. This query allows to get users in OU.

//Find users in OU
                var query = (from u in UserManager.Users
                             join ou in _userOrganizationUnitRepository.GetAll()
                             on u.Id equals ou.UserId
                             select u).Distinct().WhereIf(
                        !input.Filter.IsNullOrWhiteSpace(),
                        u =>
                            u.Name.Contains(input.Filter) ||
                            u.Surname.Contains(input.Filter) ||
                            u.UserName.Contains(input.Filter) ||
                            u.EmailAddress.Contains(input.Filter)
                    );

                //Workarround to avaid abpdatafilterexception when counting query > Performance impact by calling ToListAsync !
                var count = (await query.ToListAsync()).Count;

As you can see, a distinct keywork is added to avoid duplicated users (as a user can be on multiple OU)

If I remove Distinct keyword from the query, I have no more exception.

Any idea how to avoid this exception ?


4 Answer(s)
  • User Avatar
    0
    aaron created
    Support Team

    Can you show the error in Logs.txt?

  • User Avatar
    0
    Ricavir created

    Error log :

    ERROR 2017-12-29 14:32:46,548 [36   ] Mvc.ExceptionHandling.AbpExceptionFilter - La référence d'objet n'est pas définie à une instance d'un objet.
    System.NullReferenceException: La référence d'objet n'est pas définie à une instance d'un objet.
       à Microsoft.EntityFrameworkCore.Query.Sql.DefaultQuerySqlGenerator.VisitSelect(SelectExpression selectExpression)
       à Microsoft.EntityFrameworkCore.Query.Expressions.SelectExpression.Accept(ExpressionVisitor visitor)
       à Remotion.Linq.Parsing.ThrowingExpressionVisitor.Visit(Expression expression)
       à Microsoft.EntityFrameworkCore.Query.Sql.DefaultQuerySqlGenerator.<ProcessExpressionList>b__42_0(Expression e)
       à Microsoft.EntityFrameworkCore.Query.Sql.DefaultQuerySqlGenerator.ProcessExpressionList[T](IReadOnlyList`1 items, Action`1 itemAction, Action`1 joinAction)
       à Microsoft.EntityFrameworkCore.Query.Sql.DefaultQuerySqlGenerator.ProcessExpressionList(IReadOnlyList`1 expressions, Action`1 joinAction)
       à Microsoft.EntityFrameworkCore.Query.Sql.DefaultQuerySqlGenerator.VisitSelect(SelectExpression selectExpression)
       à Microsoft.EntityFrameworkCore.Query.Expressions.SelectExpression.Accept(ExpressionVisitor visitor)
       à Remotion.Linq.Parsing.ThrowingExpressionVisitor.Visit(Expression expression)
       à Microsoft.EntityFrameworkCore.Query.Sql.DefaultQuerySqlGenerator.GenerateSql(IReadOnlyDictionary`2 parameterValues)
       à Microsoft.EntityFrameworkCore.Query.Internal.RelationalExpressionPrinter.CommandBuilderPrinter.TryPrintConstant(ConstantExpression constantExpression, IndentedStringBuilder stringBuilder, Boolean removeFormatting)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.VisitConstant(ConstantExpression constantExpression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.Visit(Expression expression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.VisitMethodCall(MethodCallExpression methodCallExpression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.Visit(Expression expression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.VisitMethodCall(MethodCallExpression methodCallExpression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.Visit(Expression expression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.VisitMethodCall(MethodCallExpression methodCallExpression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.Visit(Expression expression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.VisitMethodCall(MethodCallExpression methodCallExpression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.Visit(Expression expression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.VisitBlock(BlockExpression blockExpression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.Visit(Expression expression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.VisitLambda[T](Expression`1 lambdaExpression)
       à System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.Visit(Expression expression)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.PrintInternal(Expression expression, Boolean removeFormatting, Nullable`1 characterLimit, Boolean highlightNonreducibleNodes)
       à Microsoft.EntityFrameworkCore.Query.Internal.ExpressionPrinter.Print(Expression expression, Boolean removeFormatting, Nullable`1 characterLimit)
       à Microsoft.EntityFrameworkCore.Internal.CoreLoggerExtensions.QueryExecutionPlanned(IDiagnosticsLogger`1 diagnostics, IExpressionPrinter expressionPrinter, Expression queryExecutorExpression)
       à Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateExecutorLambda[TResults]()
       à Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel)
       à Microsoft.EntityFrameworkCore.Storage.Database.CompileAsyncQuery[TResult](QueryModel queryModel)
       à Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileAsyncQueryCore[TResult](Expression query, INodeTypeProvider nodeTypeProvider, IDatabase database)
       à Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.&lt;&gt;c__DisplayClass24_0`1.<CompileAsyncQuery>b__0()
       à Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
       à Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddAsyncQuery[TResult](Object cacheKey, Func`1 compiler)
       à Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileAsyncQuery[TResult](Expression query)
       à Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
       à Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
       à Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
       à Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.CountAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
    
  • User Avatar
    0
    aaron created
    Support Team

    Related question: https://stackoverflow.com/questions/4472369/returning-a-distinct-iqueryable-with-linq

    var query = (from u in UserManager.Users
                 join ou in _userOrganizationUnitRepository.GetAll()
                 on u.Id equals ou.UserId
                 select u)
                 .GroupBy(u => u.Id)     // This line +
                 .Select(g => g.First()) // this line, instead of Distinct()
                 .WhereIf(
                    !input.Filter.IsNullOrWhiteSpace(),
                    u =>
                        u.Name.Contains(input.Filter) ||
                        u.Surname.Contains(input.Filter) ||
                        u.UserName.Contains(input.Filter) ||
                        u.EmailAddress.Contains(input.Filter)
                    );
    
  • User Avatar
    0
    Ricavir created

    Tks ! It's working well