From b3db2cd273fc561bc971583a04ab6a3c5f80ed40 Mon Sep 17 00:00:00 2001 From: AliReZa Sabouri Date: Thu, 15 Aug 2024 21:51:14 +0200 Subject: [PATCH] fix: Key of dictionary indexer is cached on first evaluation #201 --- src/Gridify/Builder/BaseQueryBuilder.cs | 18 +++++------ .../Gridify.Tests/IssueTests/Issue201Tests.cs | 32 +++++++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 test/Gridify.Tests/IssueTests/Issue201Tests.cs diff --git a/src/Gridify/Builder/BaseQueryBuilder.cs b/src/Gridify/Builder/BaseQueryBuilder.cs index 9131172e..fc2c7679 100644 --- a/src/Gridify/Builder/BaseQueryBuilder.cs +++ b/src/Gridify/Builder/BaseQueryBuilder.cs @@ -109,42 +109,42 @@ public TQuery Build(ExpressionSyntax expression) if (left == null || right == null) return null; var gMap = mapper.GetGMap(left); - if (gMap == null) throw new GridifyMapperException($"Mapping '{left}' not found"); + var mapTarget = gMap.To; var hasIndexer = fieldExpression?.Indexer != null; if (hasIndexer) - gMap.To = UpdateIndexerKey(gMap.To, fieldExpression!.Indexer!); + mapTarget = UpdateIndexerKey(mapTarget, fieldExpression!.Indexer!); var isNested = ((GMap)gMap).IsNestedCollection(); if (isNested) { - var result = BuildNestedQuery(gMap.To.Body, gMap, right, op); + var result = BuildNestedQuery(mapTarget.Body, gMap, right, op); if (result == null) return null; return (result, isNested); } - var query = BuildQuery(gMap.To.Body, gMap.To.Parameters[0], right, op, gMap.Convertor); + var query = BuildQuery(mapTarget.Body, mapTarget.Parameters[0], right, op, gMap.Convertor); if (query == null) return null; if (hasIndexer) - query = AddIndexerNullCheck(gMap, query); + query = AddIndexerNullCheck(mapTarget, query); return ((TQuery)query, false); } - private static object AddIndexerNullCheck(IGMap gMap, object query) + private static object AddIndexerNullCheck(LambdaExpression mapTarget, object query) { if (GridifyGlobalConfiguration.DisableNullChecks || GridifyGlobalConfiguration.EntityFrameworkCompatibilityLayer) return query; - var body = gMap.To.Body; + var body = mapTarget.Body; if (body is UnaryExpression unaryExpression) body = unaryExpression.Operand; if (body is not MethodCallExpression methodCallExpression) return query; - var containsKeyMethod = methodCallExpression.Object!.Type.GetMethod("ContainsKey", [gMap.To.Parameters[1].Type]); + var containsKeyMethod = methodCallExpression.Object!.Type.GetMethod("ContainsKey", [mapTarget.Parameters[1].Type]); if (containsKeyMethod == null) return query; var mainQuery = (LambdaExpression)query; var keyNullCheck = Expression.Call(methodCallExpression.Object!, containsKeyMethod, methodCallExpression.Arguments); @@ -198,7 +198,7 @@ private static object AddIndexerNullCheck(IGMap gMap, object query) { return BuildAlwaysFalseQuery(parameter); } - + if (value is DateTime dateTime) { if (mapper.Configuration.DefaultDateTimeKind.HasValue) diff --git a/test/Gridify.Tests/IssueTests/Issue201Tests.cs b/test/Gridify.Tests/IssueTests/Issue201Tests.cs new file mode 100644 index 00000000..dc950061 --- /dev/null +++ b/test/Gridify.Tests/IssueTests/Issue201Tests.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using Xunit; +using Xunit.Abstractions; + +namespace Gridify.Tests.IssueTests; + +public class Issue201Tests(ITestOutputHelper output) +{ + + [Fact] + public void DictionaryIndexer_ShouldUpdateTheIndexIfIsChanged() + { + // Act + var query = new QueryBuilder() + .AddMap("prop", (field, key) => field.Prop[key]) + .AddCondition("prop[44] = 2024") + .AddCondition("prop[45] = 2025") + .BuildFilteringExpression(); + + + // Assert + output.WriteLine(query.ToString()); + Assert.Contains("field.Prop.get_Item(44) == 2024", query.ToString()); + Assert.Contains("field.Prop.get_Item(45) == 2025", query.ToString()); + } + + + public class TestModel + { + public Dictionary Prop { get; set; } = new(); + } +}