Skip to content

Commit

Permalink
fix: Key of dictionary indexer is cached on first evaluation #201
Browse files Browse the repository at this point in the history
  • Loading branch information
alirezanet committed Aug 15, 2024
1 parent b670b62 commit b3db2cd
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 9 deletions.
18 changes: 9 additions & 9 deletions src/Gridify/Builder/BaseQueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>)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<T> 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);
Expand Down Expand Up @@ -198,7 +198,7 @@ private static object AddIndexerNullCheck(IGMap<T> gMap, object query)
{
return BuildAlwaysFalseQuery(parameter);
}

if (value is DateTime dateTime)
{
if (mapper.Configuration.DefaultDateTimeKind.HasValue)
Expand Down
32 changes: 32 additions & 0 deletions test/Gridify.Tests/IssueTests/Issue201Tests.cs
Original file line number Diff line number Diff line change
@@ -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<TestModel>()
.AddMap<long>("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<long, long> Prop { get; set; } = new();
}
}

0 comments on commit b3db2cd

Please sign in to comment.