Skip to content

Commit ae4a57b

Browse files
author
Bart Koelman
committed
Changed SortExpression.Elements type from IReadOnlyDictionary to IImmutableList
1 parent 48f8954 commit ae4a57b

File tree

7 files changed

+41
-23
lines changed

7 files changed

+41
-23
lines changed

src/JsonApiDotNetCore/Queries/Expressions/QueryExpressionRewriter.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public override QueryExpression VisitSort(SortExpression expression, TArgument a
136136
{
137137
if (expression != null)
138138
{
139-
IReadOnlyCollection<SortElementExpression> newElements = VisitSequence(expression.Elements, argument);
139+
IImmutableList<SortElementExpression> newElements = VisitList(expression.Elements, argument);
140140

141141
if (newElements.Count != 0)
142142
{
@@ -317,5 +317,21 @@ protected virtual IReadOnlyCollection<TExpression> VisitSequence<TExpression>(IE
317317

318318
return newElements;
319319
}
320+
321+
protected virtual IImmutableList<TExpression> VisitList<TExpression>(IImmutableList<TExpression> elements, TArgument argument)
322+
where TExpression : QueryExpression
323+
{
324+
ImmutableArray<TExpression>.Builder arrayBuilder = ImmutableArray.CreateBuilder<TExpression>(elements.Count);
325+
326+
foreach (TExpression element in elements)
327+
{
328+
if (Visit(element, argument) is TExpression newElement)
329+
{
330+
arrayBuilder.Add(newElement);
331+
}
332+
}
333+
334+
return arrayBuilder.ToImmutable();
335+
}
320336
}
321337
}

src/JsonApiDotNetCore/Queries/Expressions/SortExpression.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
2+
using System.Collections.Immutable;
33
using System.Linq;
44
using JetBrains.Annotations;
55

@@ -11,9 +11,9 @@ namespace JsonApiDotNetCore.Queries.Expressions
1111
[PublicAPI]
1212
public class SortExpression : QueryExpression
1313
{
14-
public IReadOnlyCollection<SortElementExpression> Elements { get; }
14+
public IImmutableList<SortElementExpression> Elements { get; }
1515

16-
public SortExpression(IReadOnlyCollection<SortElementExpression> elements)
16+
public SortExpression(IImmutableList<SortElementExpression> elements)
1717
{
1818
ArgumentGuard.NotNullNorEmpty(elements, nameof(elements));
1919

src/JsonApiDotNetCore/Queries/Internal/Parsing/SortParser.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Collections.Immutable;
34
using System.Linq;
45
using JetBrains.Annotations;
56
using JsonApiDotNetCore.Configuration;
@@ -40,17 +41,18 @@ protected SortExpression ParseSort()
4041
{
4142
SortElementExpression firstElement = ParseSortElement();
4243

43-
List<SortElementExpression> elements = firstElement.AsList();
44+
ImmutableArray<SortElementExpression>.Builder elementsBuilder = ImmutableArray.CreateBuilder<SortElementExpression>();
45+
elementsBuilder.Add(firstElement);
4446

4547
while (TokenStack.Any())
4648
{
4749
EatSingleCharacterToken(TokenKind.Comma);
4850

4951
SortElementExpression nextElement = ParseSortElement();
50-
elements.Add(nextElement);
52+
elementsBuilder.Add(nextElement);
5153
}
5254

53-
return new SortExpression(elements);
55+
return new SortExpression(elementsBuilder.ToImmutable());
5456
}
5557

5658
protected SortElementExpression ParseSortElement()

src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,8 @@ protected virtual SortExpression GetSort(IReadOnlyCollection<QueryExpression> ex
461461
if (sort == null)
462462
{
463463
AttrAttribute idAttribute = GetIdAttribute(resourceContext);
464-
sort = new SortExpression(new SortElementExpression(new ResourceFieldChainExpression(idAttribute), true).AsArray());
464+
var idAscendingSort = new SortElementExpression(new ResourceFieldChainExpression(idAttribute), true);
465+
sort = new SortExpression(ImmutableArray.Create(idAscendingSort));
465466
}
466467

467468
return sort;

src/JsonApiDotNetCore/Resources/JsonApiResourceDefinition.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Collections.Immutable;
34
using System.ComponentModel;
45
using System.Linq;
56
using System.Linq.Expressions;
@@ -84,18 +85,18 @@ protected SortExpression CreateSortExpressionFromLambda(PropertySortOrder keySel
8485
{
8586
ArgumentGuard.NotNull(keySelectors, nameof(keySelectors));
8687

87-
var sortElements = new List<SortElementExpression>();
88+
ImmutableArray<SortElementExpression>.Builder elementsBuilder = ImmutableArray.CreateBuilder<SortElementExpression>(keySelectors.Count);
8889

8990
foreach ((Expression<Func<TResource, dynamic>> keySelector, ListSortDirection sortDirection) in keySelectors)
9091
{
9192
bool isAscending = sortDirection == ListSortDirection.Ascending;
9293
AttrAttribute attribute = ResourceGraph.GetAttributes(keySelector).Single();
9394

9495
var sortElement = new SortElementExpression(new ResourceFieldChainExpression(attribute), isAscending);
95-
sortElements.Add(sortElement);
96+
elementsBuilder.Add(sortElement);
9697
}
9798

98-
return new SortExpression(sortElements);
99+
return new SortExpression(elementsBuilder.ToImmutable());
99100
}
100101

101102
/// <inheritdoc />

test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarExpressionRewriter.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Collections.Immutable;
34
using System.Linq;
45
using System.Reflection;
56
using JsonApiDotNetCore;
@@ -27,7 +28,6 @@ public CarExpressionRewriter(IResourceContextProvider resourceContextProvider)
2728
ResourceContext carResourceContext = resourceContextProvider.GetResourceContext<Car>();
2829

2930
_regionIdAttribute = carResourceContext.Attributes.Single(attribute => attribute.Property.Name == nameof(Car.RegionId));
30-
3131
_licensePlateAttribute = carResourceContext.Attributes.Single(attribute => attribute.Property.Name == nameof(Car.LicensePlate));
3232
}
3333

@@ -121,25 +121,25 @@ private FilterExpression CreateEqualityComparisonOnCompositeKey(ResourceFieldCha
121121

122122
public override QueryExpression VisitSort(SortExpression expression, object argument)
123123
{
124-
var newSortElements = new List<SortElementExpression>();
124+
ImmutableArray<SortElementExpression>.Builder elementsBuilder = ImmutableArray.CreateBuilder<SortElementExpression>(expression.Elements.Count);
125125

126126
foreach (SortElementExpression sortElement in expression.Elements)
127127
{
128128
if (IsSortOnCarId(sortElement))
129129
{
130130
ResourceFieldChainExpression regionIdSort = ReplaceLastAttributeInChain(sortElement.TargetAttribute, _regionIdAttribute);
131-
newSortElements.Add(new SortElementExpression(regionIdSort, sortElement.IsAscending));
131+
elementsBuilder.Add(new SortElementExpression(regionIdSort, sortElement.IsAscending));
132132

133133
ResourceFieldChainExpression licensePlateSort = ReplaceLastAttributeInChain(sortElement.TargetAttribute, _licensePlateAttribute);
134-
newSortElements.Add(new SortElementExpression(licensePlateSort, sortElement.IsAscending));
134+
elementsBuilder.Add(new SortElementExpression(licensePlateSort, sortElement.IsAscending));
135135
}
136136
else
137137
{
138-
newSortElements.Add(sortElement);
138+
elementsBuilder.Add(sortElement);
139139
}
140140
}
141141

142-
return new SortExpression(newSortElements);
142+
return new SortExpression(elementsBuilder.ToImmutable());
143143
}
144144

145145
private static bool IsSortOnCarId(SortElementExpression sortElement)

test/JsonApiDotNetCoreExampleTests/IntegrationTests/CompositeKeys/CarRepository.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ namespace JsonApiDotNetCoreExampleTests.IntegrationTests.CompositeKeys
1313
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
1414
public sealed class CarRepository : EntityFrameworkCoreRepository<Car, string>
1515
{
16-
private readonly IResourceGraph _resourceGraph;
16+
private readonly CarExpressionRewriter _writer;
1717

1818
public CarRepository(ITargetedFields targetedFields, IDbContextResolver contextResolver, IResourceGraph resourceGraph, IResourceFactory resourceFactory,
1919
IEnumerable<IQueryConstraintProvider> constraintProviders, ILoggerFactory loggerFactory)
2020
: base(targetedFields, contextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory)
2121
{
22-
_resourceGraph = resourceGraph;
22+
_writer = new CarExpressionRewriter(resourceGraph);
2323
}
2424

2525
protected override IQueryable<Car> ApplyQueryLayer(QueryLayer layer)
@@ -33,14 +33,12 @@ private void RecursiveRewriteFilterInLayer(QueryLayer queryLayer)
3333
{
3434
if (queryLayer.Filter != null)
3535
{
36-
var writer = new CarExpressionRewriter(_resourceGraph);
37-
queryLayer.Filter = (FilterExpression)writer.Visit(queryLayer.Filter, null);
36+
queryLayer.Filter = (FilterExpression)_writer.Visit(queryLayer.Filter, null);
3837
}
3938

4039
if (queryLayer.Sort != null)
4140
{
42-
var writer = new CarExpressionRewriter(_resourceGraph);
43-
queryLayer.Sort = (SortExpression)writer.Visit(queryLayer.Sort, null);
41+
queryLayer.Sort = (SortExpression)_writer.Visit(queryLayer.Sort, null);
4442
}
4543

4644
if (queryLayer.Projection != null)

0 commit comments

Comments
 (0)