Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value typed property from subquery are casted as object #775

Closed
neilbgr opened this issue Feb 9, 2024 · 4 comments
Closed

Value typed property from subquery are casted as object #775

neilbgr opened this issue Feb 9, 2024 · 4 comments
Assignees
Labels

Comments

@neilbgr
Copy link
Contributor

neilbgr commented Feb 9, 2024

All value typed properties read from subquery are casted as object and can not be compared with other same typed value.
Even trying with WrappedConstant().

Operator '!=' incompatible with operand types 'Boolean' and 'Object' (at index 6)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.CheckAndPromoteOperands(Type signatures, TokenId opId, String opName, Expression& left, Expression& right, Int32 errorPos) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 2341
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseComparisonOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 613
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLogicalAndOrOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 414
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 325
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 308
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 290
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 270
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 257
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator() in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 241
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.Parse(Type resultType, Boolean createParameterCtor) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\Parser\ExpressionParser.cs:line 156
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Type delegateType, ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicExpressionParser.cs:line 121
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicExpressionParser.cs:line 98
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, Type itType, Type resultType, String expression, Object[] values) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicExpressionParser.cs:line 357
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where(IQueryable source, ParsingConfig config, String predicate, Object[] args) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicQueryableExtensions.cs:line 2656
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where[TSource](IQueryable`1 source, ParsingConfig config, String predicate, Object[] args) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicQueryableExtensions.cs:line 2623
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where[TSource](IQueryable`1 source, String predicate, Object[] args) in C:\Dev\GitHub\System.Linq.Dynamic.Core\src\System.Linq.Dynamic.Core\DynamicQueryableExtensions.cs:line 2629

Fiddle that reproduce the issue: https://dotnetfiddle.net/slGSSp

Thanks

@StefH StefH self-assigned this Feb 9, 2024
@neilbgr
Copy link
Contributor Author

neilbgr commented Feb 9, 2024

If adding this condition after the else, my case is fixed but 2 unit tests failed...

From System.Linq.Dynamic.Core\Parser\SupportedMethods\MethodFinder.cs line 132:

  for (var i = 0; i < args.Length; i++)
  {
      if (args[i].Type != methodData.Args[i].Type &&
          args[i].Type.IsArray && methodData.Args[i].Type.IsArray &&
          args[i].Type != typeof(string) && methodData.Args[i].Type == typeof(object[]))
      {
          args[i] = _expressionHelper.ConvertAnyArrayToObjectArray(args[i]);
      }
      else if (methodData.Args[i].Type != typeof(object)) // Fix (or hack?)
      {
          args[i] = methodData.Args[i];
      }
  }

image

@neilbgr
Copy link
Contributor Author

neilbgr commented Feb 9, 2024

My unit test (in file test\System.Linq.Dynamic.Core.Tests\QueryableTests.UseParameterizedNamesInDynamicQuery.cs):

public void Issue775()
{
    var list = new List<Customer>
    {
        new()
        {
            CustomerID = 1,
            Name = "Duffy",
            GenderType = Gender.Female
        },
        new()
        {
            CustomerID = 2,
            Name = "Garry",
            GenderType = Gender.Male
        },
        new()
        {
            CustomerID = 3,
            Name = "John",
            GenderType = Gender.Male
        }
    };

    var config = new ParsingConfig
    {
        UseParameterizedNamesInDynamicQuery = true
    };

    var subquery = list.AsQueryable().Where(_ => _.CustomerID == 2);
    //var subquery = list.AsQueryable().Where("CustomerID == 2");

    // Act
    var result = list.AsQueryable().Where(config, "CustomerID != @0.Select(CustomerID).FirstOrDefault()", subquery).ToArray();

    // Assert
    result.Should().HaveCount(2);
}

@StefH
Copy link
Collaborator

StefH commented Feb 9, 2024

I was just also debugging this part.

The root cause is that object is detected from that IEnnumerable helper class.

@StefH
Copy link
Collaborator

StefH commented Feb 10, 2024

#777

@StefH StefH added the bug label Feb 29, 2024
@StefH StefH closed this as completed Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants