From 95c805b3af5534a7b65b56f74f4e66f18e567344 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Mon, 21 Feb 2022 22:02:39 +0100 Subject: [PATCH] Fix logic for indexer when parameter-type differs --- NuGet.txt | 6 +++++ .../Parser/ExpressionParser.cs | 11 +++++++- .../QueryableTests.Select.cs | 25 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/NuGet.txt b/NuGet.txt index d16d07b4..651eb880 100644 --- a/NuGet.txt +++ b/NuGet.txt @@ -1,3 +1,9 @@ +Open Command Prompt + System.Linq.Dynamic.Core\src> +del /S *.nupkg + +VS rebuild + dotnet nuget push **\*.nupkg --source https://api.nuget.org/v3/index.json --api-key x diff --git a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs index 4a5187a3..6a6a65c2 100644 --- a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs +++ b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs @@ -1965,7 +1965,16 @@ Expression ParseElementAccess(Expression expr) throw ParseError(errorPos, Res.NoApplicableIndexer, TypeHelper.GetTypeName(expr.Type)); case 1: - return Expression.Call(expr, (MethodInfo)mb, args); + var indexMethod = (MethodInfo)mb; + var indexParameterType = indexMethod.GetParameters().First().ParameterType; + + var indexArgumentExpression = args[0]; // Indexer only has 1 parameter, so we can use args[0] here + if (indexParameterType != indexArgumentExpression.Type) + { + indexArgumentExpression = Expression.Convert(indexArgumentExpression, indexParameterType); + } + + return Expression.Call(expr, indexMethod, indexArgumentExpression); default: throw ParseError(errorPos, Res.AmbiguousIndexerInvocation, TypeHelper.GetTypeName(expr.Type)); diff --git a/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs b/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs index a0873b4a..c349723f 100644 --- a/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs +++ b/test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs @@ -2,10 +2,12 @@ using System.Collections.Generic; using System.Linq.Dynamic.Core.Exceptions; using System.Linq.Dynamic.Core.Tests.Helpers.Models; +using FluentAssertions; using Linq.PropertyTranslator.Core; using QueryInterceptor.Core; using Xunit; using NFluent; +using Newtonsoft.Json.Linq; #if EFCORE using Microsoft.AspNetCore.Identity; #else @@ -348,6 +350,29 @@ public void Select_Dynamic_RenameParameterExpression_Is_True() Check.That(result).Equals("System.Int32[].Select(it => (it * it))"); } + [Fact] + public void Select_Dynamic_JObject_With_Array_Should_Use_Correct_Indexer() + { + // Arrange + var j = new JObject + { + {"I", new JValue(9)}, + {"A", new JArray(new[] {1,2,3}) } , + {"L", new JValue(5)} + }; + var queryable = new[] { j }.AsQueryable(); + + // Act + var result = queryable.Select("new (long(I) as I, (new [] { long(A[0]), long(A[1]), long(A[2])}) as A, long(L) as L)").ToDynamicArray().First(); + + // Assert + Assert.Equal(9, result.I); + Assert.Equal(5, result.L); + Assert.Equal(1, result.A[0]); + Assert.Equal(2, result.A[1]); + Assert.Equal(3, result.A[2]); + } + [Fact] public void Select_Dynamic_ReservedKeyword() {