Skip to content

Commit 6774939

Browse files
authored
Fix allocations in fallback code (#529)
1 parent d5aa7ec commit 6774939

File tree

6 files changed

+53
-18
lines changed

6 files changed

+53
-18
lines changed

src/Ardalis.Specification.EntityFrameworkCore/Evaluators/IncludeStringEvaluator.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,22 @@ public IQueryable<T> GetQuery<T>(IQueryable<T> query, ISpecification<T> specific
1313
if (specification is Specification<T> spec)
1414
{
1515
if (spec.OneOrManyIncludeStrings.IsEmpty) return query;
16-
if (spec.OneOrManyIncludeStrings.SingleOrDefault is { } includeString)
16+
if (spec.OneOrManyIncludeStrings.SingleOrDefault is { } includeStr)
1717
{
18-
return query.Include(includeString);
18+
return query.Include(includeStr);
1919
}
20+
21+
foreach (var includeString in spec.OneOrManyIncludeStrings.List)
22+
{
23+
query = query.Include(includeString);
24+
}
25+
return query;
2026
}
2127

2228
foreach (var includeString in specification.IncludeStrings)
2329
{
2430
query = query.Include(includeString);
2531
}
26-
2732
return query;
2833
}
2934
}

src/Ardalis.Specification.EntityFrameworkCore/Evaluators/QueryTagEvaluator.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@ public IQueryable<T> GetQuery<T>(IQueryable<T> query, ISpecification<T> specific
1717
{
1818
return query.TagWith(spec.OneOrManyQueryTags.Single);
1919
}
20+
21+
foreach (var tag in spec.OneOrManyQueryTags.List)
22+
{
23+
query = query.TagWith(tag);
24+
}
25+
return query;
2026
}
2127

2228
foreach (var tag in specification.QueryTags)
2329
{
2430
query = query.TagWith(tag);
2531
}
26-
2732
return query;
2833
}
2934
}

src/Ardalis.Specification/Evaluators/SearchMemoryEvaluator.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,19 @@ public IEnumerable<T> Evaluate<T>(IEnumerable<T> query, ISpecification<T> specif
3333
// This is just to cover the case where users have custom ISpecification<T> implementation but use our evaluator.
3434
// We'll fall back to LINQ for this case.
3535

36-
foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup))
36+
return Fallback(query, specification);
37+
38+
static IEnumerable<T> Fallback(IEnumerable<T> query, ISpecification<T> specification)
3739
{
38-
query = query.Where(x => searchGroup.Any(c => c.SelectorFunc(x)?.Like(c.SearchTerm) ?? false));
40+
foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup))
41+
{
42+
query = query.Where(x => searchGroup.Any(c => c.SelectorFunc(x)?.Like(c.SearchTerm) ?? false));
43+
}
44+
return query;
3945
}
40-
41-
return query;
4246
}
4347

48+
4449
private sealed class SpecSingleLikeIterator<TSource> : Iterator<TSource>
4550
{
4651
private readonly IEnumerable<TSource> _source;

src/Ardalis.Specification/Evaluators/WhereEvaluator.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,18 @@ public IQueryable<T> GetQuery<T>(IQueryable<T> query, ISpecification<T> specific
2424
{
2525
return query.Where(whereExpression.Filter);
2626
}
27+
28+
foreach (var whereExpr in spec.OneOrManyWhereExpressions.List)
29+
{
30+
query = query.Where(whereExpr.Filter);
31+
}
32+
return query;
2733
}
2834

2935
foreach (var whereExpression in specification.WhereExpressions)
3036
{
3137
query = query.Where(whereExpression.Filter);
3238
}
33-
3439
return query;
3540
}
3641

@@ -44,13 +49,18 @@ public IEnumerable<T> Evaluate<T>(IEnumerable<T> query, ISpecification<T> specif
4449
{
4550
return query.Where(whereExpression.FilterFunc);
4651
}
52+
53+
foreach (var whereExpr in spec.OneOrManyWhereExpressions.List)
54+
{
55+
query = query.Where(whereExpr.FilterFunc);
56+
}
57+
return query;
4758
}
4859

4960
foreach (var whereExpression in specification.WhereExpressions)
5061
{
5162
query = query.Where(whereExpression.FilterFunc);
5263
}
53-
5464
return query;
5565
}
5666
}

src/Ardalis.Specification/Validators/SearchValidator.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,18 @@ public bool IsValid<T>(T entity, ISpecification<T> specification)
2424
// This is just to cover the case where users have custom ISpecification<T> implementation but use our validator.
2525
// We'll fall back to LINQ for this case.
2626

27-
foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup))
27+
return Fallback(entity, specification);
28+
29+
static bool Fallback(T entity, ISpecification<T> specification)
2830
{
29-
if (!searchGroup.Any(c => c.SelectorFunc(entity)?.Like(c.SearchTerm) ?? false))
30-
return false;
31-
}
31+
foreach (var searchGroup in specification.SearchCriterias.GroupBy(x => x.SearchGroup))
32+
{
33+
if (!searchGroup.Any(c => c.SelectorFunc(entity)?.Like(c.SearchTerm) ?? false))
34+
return false;
35+
}
3236

33-
return true;
37+
return true;
38+
}
3439
}
3540

3641
// This would be simpler using Span<SearchExpressionInfo<T>>

src/Ardalis.Specification/Validators/WhereValidator.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@ public bool IsValid<T>(T entity, ISpecification<T> specification)
1414
{
1515
return whereExpression.FilterFunc(entity);
1616
}
17+
18+
foreach (var whereExpr in spec.OneOrManyWhereExpressions.List)
19+
{
20+
if (whereExpr.FilterFunc(entity) == false) return false;
21+
}
22+
return true;
1723
}
1824

19-
foreach (var whereExpression in specification.WhereExpressions)
25+
foreach (var whereExpr in specification.WhereExpressions)
2026
{
21-
if (whereExpression.FilterFunc(entity) == false) return false;
27+
if (whereExpr.FilterFunc(entity) == false) return false;
2228
}
23-
2429
return true;
2530
}
2631
}

0 commit comments

Comments
 (0)