From 6171d256a4260344f4ad123e745aa77e5994e45d Mon Sep 17 00:00:00 2001
From: AliReZa Sabouri <7004080+alirezanet@users.noreply.github.com>
Date: Fri, 10 Dec 2021 17:42:38 +0330
Subject: [PATCH] Next- v2.4.6 (#54)
* update ordering description
* update packages
* Lazy map generation. performance improvement
* benchmark lazy map generation
* remove public access to fixMapper method
* update to v2.4.6
* update library comparision benchmark result
* fix spelling mistake
* AddMap always throw exception
* check IgnoreNotMappedFields in fixMapper
---
benchmark/Benchmark.csproj | 6 +-
benchmark/GridifyMapperUsages.cs | 149 ++++++++++++++++++
.../LibraryComparisionFilteringBenchmark.cs | 56 ++-----
benchmark/Program.cs | 1 +
docs/guide/README.md | 22 +--
docs/guide/autoMapper.md | 2 -
docs/guide/filtering.md | 2 +-
docs/guide/getting-started.md | 2 +-
docs/guide/ordering.md | 2 +-
.../Gridify.EntityFramework.csproj | 2 +-
.../GridifyExtensions.cs | 15 +-
src/Gridify/Gridify.csproj | 2 +-
src/Gridify/GridifyExtensions.cs | 133 ++++++++++++----
src/Gridify/GridifyMapper.cs | 28 +++-
src/Gridify/IGridifyMapper.cs | 3 +-
.../EntityFramework6IntegrationTests.csproj | 4 +-
.../packages.config | 2 +-
.../EntityFrameworkIntegrationTests.cs.csproj | 4 +-
...rameworkSqlProviderIntegrationTests.csproj | 6 +-
test/Gridify.Tests/Gridify.Tests.csproj | 7 +-
20 files changed, 334 insertions(+), 114 deletions(-)
create mode 100644 benchmark/GridifyMapperUsages.cs
diff --git a/benchmark/Benchmark.csproj b/benchmark/Benchmark.csproj
index 803c242c..034107fe 100644
--- a/benchmark/Benchmark.csproj
+++ b/benchmark/Benchmark.csproj
@@ -7,10 +7,10 @@
-
+
-
-
+
+
diff --git a/benchmark/GridifyMapperUsages.cs b/benchmark/GridifyMapperUsages.cs
new file mode 100644
index 00000000..d29d38c6
--- /dev/null
+++ b/benchmark/GridifyMapperUsages.cs
@@ -0,0 +1,149 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Engines;
+using BenchmarkDotNet.Order;
+using Gridify;
+using Gridify.Tests;
+
+namespace Benchmarks
+{
+ [MemoryDiagnoser]
+ [RPlotExporter]
+ [Orderer(SummaryOrderPolicy.FastestToSlowest)]
+ public class GridifyMapperUsages
+ {
+ private static readonly Consumer Consumer = new();
+ private TestClass[] _data;
+ private Func compiled1;
+ private Func compiled2;
+ private Func compiled3;
+
+ private IQueryable Ds => _data.AsQueryable();
+ private IEnumerable EnumerableDs => _data.ToList();
+ private IGridifyMapper ggm { get; set; }
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _data = GetSampleData().ToArray();
+
+ ggm = new GridifyMapper().GenerateMappings();
+
+ // compiled query (this is not included in our readme benchmarks)
+ var gq1 = new GridifyQuery() { Filter = "Name=*a" };
+ var gq2 = new GridifyQuery() { Filter = "Id>5" };
+ var gq3 = new GridifyQuery() { Filter = "Name=Ali" };
+ compiled1 = gq1.GetFilteringExpression(ggm).Compile();
+ compiled2 = gq2.GetFilteringExpression(ggm).Compile();
+ compiled3 = gq3.GetFilteringExpression(ggm).Compile();
+ }
+
+
+ [Benchmark(Baseline = true)]
+ public void NativeLinQ()
+ {
+ Ds.Where(q => q.Name.Contains("a")).Consume(Consumer);
+ Ds.Where(q => q.Id > 5).Consume(Consumer);
+ Ds.Where(q => q.Name == "Ali").Consume(Consumer);
+ }
+ [Benchmark]
+ public void Gridify_GlobalMapper()
+ {
+ Ds.ApplyFiltering("Name=*a", ggm).Consume(Consumer);
+ Ds.ApplyFiltering("Id>5", ggm).Consume(Consumer);
+ Ds.ApplyFiltering("Name=Ali", ggm).Consume(Consumer);
+ }
+ [Benchmark]
+ public void Gridify_SingleMapper_Generated()
+ {
+ var gm = new GridifyMapper().GenerateMappings();
+ Ds.ApplyFiltering("Name=*a", gm).Consume(Consumer);
+ Ds.ApplyFiltering("Id>5", gm).Consume(Consumer);
+ Ds.ApplyFiltering("Name=Ali", gm).Consume(Consumer);
+ }
+
+ [Benchmark]
+ public void Gridify_SingleMapper_Manual()
+ {
+ var gm = new GridifyMapper()
+ .AddMap("name")
+ .AddMap("id");
+
+ Ds.ApplyFiltering("Name=*a", gm).Consume(Consumer);
+ Ds.ApplyFiltering("Id>5", gm).Consume(Consumer);
+ Ds.ApplyFiltering("Name=Ali", gm).Consume(Consumer);
+ }
+
+ [Benchmark]
+ public void Gridify_NoMapper()
+ {
+ Ds.ApplyFiltering("Name=*a").Consume(Consumer);
+ Ds.ApplyFiltering("Id>5").Consume(Consumer);
+ Ds.ApplyFiltering("Name=Ali").Consume(Consumer);
+ }
+ [Benchmark]
+ public void Gridify_EachAction_Generated()
+ {
+ Ds.ApplyFiltering("Name=*a", new GridifyMapper().GenerateMappings()).Consume(Consumer);
+ Ds.ApplyFiltering("Id>5", new GridifyMapper().GenerateMappings()).Consume(Consumer);
+ Ds.ApplyFiltering("Name=Ali", new GridifyMapper().GenerateMappings()).Consume(Consumer);
+ }
+
+ // [Benchmark]
+ // public void GridifyCompiled()
+ // {
+ // EnumerableDs.Where(compiled1).Consume(Consumer);
+ // EnumerableDs.Where(compiled2).Consume(Consumer);
+ // EnumerableDs.Where(compiled3).Consume(Consumer);
+ // }
+
+ public static IEnumerable GetSampleData()
+ {
+ var lst = new List();
+ lst.Add(new TestClass(1, "John", null, Guid.NewGuid(), DateTime.Now));
+ lst.Add(new TestClass(2, "Bob", null, Guid.NewGuid(), DateTime.UtcNow));
+ lst.Add(new TestClass(3, "Jack", (TestClass)lst[0].Clone(), Guid.Empty, DateTime.Now.AddDays(2)));
+ lst.Add(new TestClass(4, "Rose", null, Guid.Parse("e2cec5dd-208d-4bb5-a852-50008f8ba366")));
+ lst.Add(new TestClass(5, "Ali", null));
+ lst.Add(new TestClass(6, "Hamid", (TestClass)lst[0].Clone(), Guid.Parse("de12bae1-93fa-40e4-92d1-2e60f95b468c")));
+ lst.Add(new TestClass(7, "Hasan", (TestClass)lst[1].Clone()));
+ lst.Add(new TestClass(8, "Farhad", (TestClass)lst[2].Clone(), Guid.Empty));
+ lst.Add(new TestClass(9, "Sara", null));
+ lst.Add(new TestClass(10, "Jorge", null));
+ lst.Add(new TestClass(11, "joe", null));
+ lst.Add(new TestClass(12, "jimmy", (TestClass)lst[0].Clone()));
+ lst.Add(new TestClass(13, "Nazanin", null));
+ lst.Add(new TestClass(14, "Reza", null));
+ lst.Add(new TestClass(15, "Korosh", (TestClass)lst[0].Clone()));
+ lst.Add(new TestClass(16, "Kamran", (TestClass)lst[1].Clone()));
+ lst.Add(new TestClass(17, "Saeid", (TestClass)lst[2].Clone()));
+ lst.Add(new TestClass(18, "jessi==ca", null));
+ lst.Add(new TestClass(19, "Ped=ram", null));
+ lst.Add(new TestClass(20, "Peyman!", null));
+ lst.Add(new TestClass(21, "Fereshte", null));
+ lst.Add(new TestClass(22, "LIAM", null));
+ lst.Add(new TestClass(22, @"\Liam", null));
+ lst.Add(new TestClass(23, "LI | AM", null));
+ lst.Add(new TestClass(24, "(LI,AM)", null));
+ return lst;
+ }
+ }
+}
+
+// BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
+// 11th Gen Intel Core i5-11400F 2.60GHz, 1 CPU, 12 logical and 6 physical cores
+// .NET SDK=6.0.100
+// [Host] : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
+// DefaultJob : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
+//
+//
+// | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Allocated |
+// |------------------------------- |---------:|---------:|---------:|------:|--------:|-------:|-------:|----------:|
+// | NativeLinQ | 826.9 us | 13.49 us | 12.61 us | 1.00 | 0.00 | 4.8828 | 1.9531 | 35 KB |
+// | Gridify_SingleMapper_Manual | 846.4 us | 8.64 us | 7.66 us | 1.02 | 0.02 | 5.8594 | 2.9297 | 41 KB |
+// | Gridify_SingleMapper_Generated | 847.8 us | 10.72 us | 9.51 us | 1.02 | 0.02 | 6.8359 | 2.9297 | 43 KB |
+// | Gridify_GlobalMapper | 854.6 us | 15.35 us | 19.42 us | 1.04 | 0.03 | 5.8594 | 2.9297 | 40 KB |
+// | Gridify_NoMapper | 876.5 us | 17.33 us | 28.48 us | 1.07 | 0.04 | 5.8594 | 1.9531 | 44 KB |
+// | Gridify_EachAction_Generated | 877.4 us | 16.82 us | 20.66 us | 1.06 | 0.03 | 7.8125 | 3.9063 | 48 KB |
diff --git a/benchmark/LibraryComparisionFilteringBenchmark.cs b/benchmark/LibraryComparisionFilteringBenchmark.cs
index 6828f6a4..a861238c 100644
--- a/benchmark/LibraryComparisionFilteringBenchmark.cs
+++ b/benchmark/LibraryComparisionFilteringBenchmark.cs
@@ -22,35 +22,20 @@ public class LibraryComparisionFilteringBenchmark
{
private static readonly Consumer Consumer = new();
private TestClass[] _data;
- private Func compiled1;
- private Func compiled2;
- private Func compiled3;
private IQueryable Ds => _data.AsQueryable();
- private IEnumerable EnumerableDs => _data.ToList();
- private IGridifyMapper gm { get; set; }
[GlobalSetup]
public void Setup()
{
_data = GetSampleData().ToArray();
-
- gm = new GridifyMapper().GenerateMappings();
-
- // compiled query (this is not included in our readme benchmarks)
- var gq1 = new GridifyQuery() { Filter = "Name=*a" };
- var gq2 = new GridifyQuery() { Filter = "Id>5" };
- var gq3 = new GridifyQuery() { Filter = "Name=Ali" };
- compiled1 = gq1.GetFilteringExpression(gm).Compile();
- compiled2 = gq2.GetFilteringExpression(gm).Compile();
- compiled3 = gq3.GetFilteringExpression(gm).Compile();
}
[Benchmark(Baseline = true)]
public void NativeLinQ()
{
- Ds.Where(q => q.Name.Contains("a")).Consume(Consumer);
+ Ds.Where(q => q.Name.Contains('a')).Consume(Consumer);
Ds.Where(q => q.Id > 5).Consume(Consumer);
Ds.Where(q => q.Name == "Ali").Consume(Consumer);
}
@@ -58,19 +43,12 @@ public void NativeLinQ()
[Benchmark]
public void Gridify()
{
+ var gm = new GridifyMapper().GenerateMappings();
Ds.ApplyFiltering("Name=*a", gm).Consume(Consumer);
Ds.ApplyFiltering("Id>5", gm).Consume(Consumer);
Ds.ApplyFiltering("Name=Ali", gm).Consume(Consumer);
}
- // [Benchmark] // compiled query (this is not included in our readme benchmarks)w
- public void GridifyCompiled()
- {
- EnumerableDs.Where(compiled1).Consume(Consumer);
- EnumerableDs.Where(compiled2).Consume(Consumer);
- EnumerableDs.Where(compiled3).Consume(Consumer);
- }
-
[Benchmark]
public void Fop()
{
@@ -131,19 +109,17 @@ public static IEnumerable GetSampleData()
}
}
-/* Last Run:
- BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19043.1237 (21H1/May2021Update)
-11th Gen Intel Core i5-11400F 2.60GHz, 1 CPU, 12 logical and 6 physical cores
-.NET SDK=5.0.301
-[Host] : .NET 5.0.7 (5.0.721.25508), X64 RyuJIT
-DefaultJob : .NET 5.0.7 (5.0.721.25508), X64 RyuJIT
-
-
-| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Allocated |
-|------------ |-----------:|---------:|---------:|------:|--------:|--------:|----------:|
-| Native LINQ | 740.9 us | 7.80 us | 6.92 us | 1.00 | 5.8594 | 2.9297 | 37 KB |
-| Gridify | 762.6 us | 10.06 us | 9.41 us | 1.03 | 5.8594 | 2.9297 | 39 KB |
-| DynamicLinq | 902.1 us | 11.56 us | 10.81 us | 1.22 | 19.5313 | 9.7656 | 122 KB |
-| Sieve | 977.9 us | 6.80 us | 6.37 us | 1.32 | 7.8125 | 3.9063 | 54 KB |
-| Fop | 2,959.8 us | 39.11 us | 36.58 us | 3.99 | 46.8750 | 23.4375 | 306 KB |
-*/
+// BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
+// 11th Gen Intel Core i5-11400F 2.60GHz, 1 CPU, 12 logical and 6 physical cores
+// .NET SDK=6.0.100
+// [Host] : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
+// DefaultJob : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
+//
+//
+// | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Allocated |
+// |------------ |-----------:|---------:|---------:|------:|--------:|--------:|--------:|----------:|
+// | NativeLinQ | 823.8 us | 11.18 us | 9.91 us | 1.00 | 0.00 | 4.8828 | 1.9531 | 35 KB |
+// | Gridify | 853.1 us | 13.88 us | 12.98 us | 1.03 | 0.02 | 6.8359 | 2.9297 | 43 KB |
+// | DynamicLinQ | 967.3 us | 6.65 us | 5.55 us | 1.17 | 0.01 | 19.5313 | 9.7656 | 123 KB |
+// | Sieve | 1,275.2 us | 5.62 us | 4.70 us | 1.55 | 0.02 | 7.8125 | 3.9063 | 55 KB |
+// | Fop | 3,480.2 us | 55.81 us | 52.21 us | 4.23 | 0.06 | 54.6875 | 27.3438 | 343 KB |
diff --git a/benchmark/Program.cs b/benchmark/Program.cs
index 718ffe99..3d62ac0a 100644
--- a/benchmark/Program.cs
+++ b/benchmark/Program.cs
@@ -8,6 +8,7 @@ public class Program
private static void Main()
{
BenchmarkRunner.Run();
+ // BenchmarkRunner.Run();
// BenchmarkRunner.Run();
// BenchmarkRunner.Run();
Console.Read();
diff --git a/docs/guide/README.md b/docs/guide/README.md
index 5d787cea..328c625b 100644
--- a/docs/guide/README.md
+++ b/docs/guide/README.md
@@ -17,18 +17,18 @@ Be sure to check out these examples
Filtering is the most expensive feature in gridify. the following benchmark is comparing filtering in the most known dynamic linq libraries. As you can see, gridify has the closest result to the native linq.
-| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Allocated |
-|------------ |-----------:|---------:|---------:|------:|--------:|--------:|----------:|
-| Native LINQ | 740.9 us | 7.80 us | 6.92 us | 1.00 | 5.8594 | 2.9297 | 37 KB |
-| **Gridify*** | 762.6 us | 10.06 us | 9.41 us | 1.03 | 5.8594 | 2.9297 | 39 KB |
-| DynamicLinq | 902.1 us | 11.56 us | 10.81 us | 1.22 | 19.5313 | 9.7656 | 122 KB |
-| Sieve | 977.9 us | 6.80 us | 6.37 us | 1.32 | 7.8125 | 3.9063 | 54 KB |
-| Fop | 2,959.8 us | 39.11 us | 36.58 us | 3.99 | 46.8750 | 23.4375 | 306 KB |
+| Method | Mean | Error | Ratio | Gen 0 | Gen 1 | Allocated |
+|------------ |-----------:|---------:|------:|--------:|--------:|----------:|
+| NativeLinQ | 823.8 us | 11.18 us | 1.00 | 4.8828 | 1.9531 | 35 KB |
+| ***Gridify** | 853.1 us | 13.88 us | **1.03** | 6.8359 | 2.9297 | 43 KB |
+| DynamicLinQ | 967.3 us | 6.65 us | 1.17 | 19.5313 | 9.7656 | 123 KB |
+| Sieve | 1,275.2 us | 5.62 us | 1.55 | 7.8125 | 3.9063 | 55 KB |
+| Fop | 3,480.2 us | 55.81 us | 4.23 | 54.6875 | 27.3438 | 343 KB |
::: details
-BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19043.1237 (21H1/May2021Update)
+BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
11th Gen Intel Core i5-11400F 2.60GHz, 1 CPU, 12 logical and 6 physical cores
-.NET SDK=5.0.301
-[Host] : .NET 5.0.7 (5.0.721.25508), X64 RyuJIT
-DefaultJob : .NET 5.0.7 (5.0.721.25508), X64 RyuJIT
+.NET SDK=6.0.100
+ [Host] : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
+ DefaultJob : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT
:::
diff --git a/docs/guide/autoMapper.md b/docs/guide/autoMapper.md
index 2e25c09d..a24d0bc3 100644
--- a/docs/guide/autoMapper.md
+++ b/docs/guide/autoMapper.md
@@ -23,7 +23,6 @@ Gridify library does not have a built-in GridifyTo extension method because we d
public static Paging GridifyTo(this IQueryable query,
IMapper autoMapper, IGridifyQuery gridifyQuery, IGridifyMapper mapper = null)
{
- mapper = mapper.FixMapper();
var res = query.GridifyQueryable(gridifyQuery, mapper);
return new Paging (res.Count , res.Query.ProjectTo(autoMapper.ConfigurationProvider).ToList());
}
@@ -34,7 +33,6 @@ public static Paging GridifyTo(this IQuerya
public static async Task> GridifyToAsync(this IQueryable query,
IMapper autoMapper, IGridifyQuery gridifyQuery, IGridifyMapper mapper = null)
{
- mapper = mapper.FixMapper();
var res = await query.GridifyQueryableAsync(gridifyQuery, mapper);
return new Paging (res.Count , await res.Query.ProjectTo(autoMapper.ConfigurationProvider).ToListAsync());
}
diff --git a/docs/guide/filtering.md b/docs/guide/filtering.md
index 43d7f258..a4fc3c3f 100644
--- a/docs/guide/filtering.md
+++ b/docs/guide/filtering.md
@@ -57,7 +57,7 @@ this query matches with JOHN - john - John - jOHn ...
## Escaping
-Gridify have five special operators `, | ( ) /i` to handle complex queries and case-insensitive searchs. If you want to use these characters in your query values (after conditional operator), you should add a backslash \
before them. having this regex could be helpfull `([(),|]|\/i)`.
+Gridify have five special operators `, | ( ) /i` to handle complex queries and case-insensitive searches. If you want to use these characters in your query values (after conditional operator), you should add a backslash \
before them. having this regex could be helpfull `([(),|]|\/i)`.
JavaScript escape example:
``` javascript
diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md
index 1a82b961..ad389dd9 100644
--- a/docs/guide/getting-started.md
+++ b/docs/guide/getting-started.md
@@ -2,7 +2,7 @@
export default {
setup() {
return {
- version: '2.4.5'
+ version: '2.4.6'
}
}
}
diff --git a/docs/guide/ordering.md b/docs/guide/ordering.md
index 09d4ad33..0d7633d7 100644
--- a/docs/guide/ordering.md
+++ b/docs/guide/ordering.md
@@ -1,6 +1,6 @@
# Ordering Syntax
-The ordering query expression can be built with a comma-separated field names followed by **`asc`** or **`desc`** keywords.
+The ordering query expression can be built with a comma-delimited ordered list of field/property names followed by **`asc`** or **`desc`** keywords.
by default, if you don't add these keywords, gridify assumes you need Ascending ordering.
diff --git a/src/Gridify.EntityFramework/Gridify.EntityFramework.csproj b/src/Gridify.EntityFramework/Gridify.EntityFramework.csproj
index 111ce60f..4dcfe053 100644
--- a/src/Gridify.EntityFramework/Gridify.EntityFramework.csproj
+++ b/src/Gridify.EntityFramework/Gridify.EntityFramework.csproj
@@ -2,7 +2,7 @@
netstandard2.0
Gridify.EntityFramework
- 2.4.5
+ 2.4.6
Alireza Sabouri
TuxTeam
Gridify (EntityFramework), Easy and optimized way to apply Filtering, Sorting, and Pagination using text-based data.
diff --git a/src/Gridify.EntityFramework/GridifyExtensions.cs b/src/Gridify.EntityFramework/GridifyExtensions.cs
index a87be682..9cf11765 100644
--- a/src/Gridify.EntityFramework/GridifyExtensions.cs
+++ b/src/Gridify.EntityFramework/GridifyExtensions.cs
@@ -21,9 +21,8 @@ public async static Task> GridifyQueryableAsync(this IQuer
public static async Task> GridifyAsync(this IQueryable query, IGridifyQuery gridifyQuery, IGridifyMapper mapper = null)
{
- mapper = mapper.FixMapper();
- var res = await query.GridifyQueryableAsync(gridifyQuery, mapper);
- return new Paging(res.Count, await res.Query.ToListAsync());
+ var (count, queryable) = await query.GridifyQueryableAsync(gridifyQuery, mapper);
+ return new Paging(count, await queryable.ToListAsync());
}
public async static Task> GridifyQueryableAsync(this IQueryable query, IGridifyQuery gridifyQuery,
@@ -36,13 +35,13 @@ public async static Task> GridifyQueryableAsync(this IQuer
return new QueryablePaging(count, query);
}
- public static async Task> GridifyAsync(this IQueryable query, IGridifyQuery gridifyQuery, CancellationToken token, IGridifyMapper mapper = null)
+ public static async Task> GridifyAsync(this IQueryable query, IGridifyQuery gridifyQuery, CancellationToken token,
+ IGridifyMapper mapper = null)
{
- mapper = mapper.FixMapper();
- var res = await query.GridifyQueryableAsync(gridifyQuery, mapper, token);
- return new Paging(res.Count, await res.Query.ToListAsync(token));
+ var (count, queryable) = await query.GridifyQueryableAsync(gridifyQuery, mapper, token);
+ return new Paging(count, await queryable.ToListAsync(token));
}
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/src/Gridify/Gridify.csproj b/src/Gridify/Gridify.csproj
index 6b9bd64b..e3eabebc 100644
--- a/src/Gridify/Gridify.csproj
+++ b/src/Gridify/Gridify.csproj
@@ -3,7 +3,7 @@
netstandard2.0
Gridify
- 2.4.5
+ 2.4.6
Alireza Sabouri
TuxTeam
Gridify, Easy and optimized way to apply Filtering, Sorting, and Pagination using text-based data.
diff --git a/src/Gridify/GridifyExtensions.cs b/src/Gridify/GridifyExtensions.cs
index a8b76cc6..b9ae386f 100644
--- a/src/Gridify/GridifyExtensions.cs
+++ b/src/Gridify/GridifyExtensions.cs
@@ -41,13 +41,12 @@ public static Expression> GetFilteringExpression(this IGridifyF
if (string.IsNullOrWhiteSpace(gridifyFiltering.Filter))
throw new GridifyQueryException("Filter is not defined");
- mapper = mapper.FixMapper();
-
var syntaxTree = SyntaxTree.Parse(gridifyFiltering.Filter!);
if (syntaxTree.Diagnostics.Any())
throw new GridifyFilteringException(syntaxTree.Diagnostics.Last()!);
+ mapper = mapper.FixMapper(syntaxTree);
var (queryExpression, _) = ExpressionToQueryConvertor.GenerateQuery(syntaxTree.Root, mapper);
if (queryExpression == null) throw new GridifyQueryException("Can not create expression with current data");
return queryExpression;
@@ -56,17 +55,34 @@ public static Expression> GetFilteringExpression(this IGridifyF
public static IEnumerable>> GetOrderingExpressions(this IGridifyOrdering gridifyOrdering,
IGridifyMapper? mapper = null)
{
- mapper = mapper.FixMapper();
-
if (string.IsNullOrWhiteSpace(gridifyOrdering.OrderBy))
throw new GridifyQueryException("OrderBy is not defined or not Found");
- foreach (var (member, _) in ParseOrderings(gridifyOrdering.OrderBy!))
+
+ var members = ParseOrderings(gridifyOrdering.OrderBy!).Select(q => q.memberName).ToList();
+ if (mapper is null)
{
- // skip if there is no mappings available
- if (!mapper.HasMap(member)) continue;
+ foreach (var member in members)
+ {
+ Expression>? exp = null;
+ try
+ {
+ exp = GridifyMapper.CreateExpression(member);
+ }
+ catch (Exception)
+ {
+ // skip if there is no mappings available
+ }
- yield return mapper.GetExpression(member)!;
+ if (exp != null) yield return exp;
+ }
+ }
+ else
+ {
+ foreach (var member in members.Where(mapper.HasMap))
+ {
+ yield return mapper.GetExpression(member)!;
+ }
}
}
@@ -86,11 +102,41 @@ private static IGridifyMapper GetDefaultMapper()
/// if given mapper was null this function creates default generated mapper
///
/// a GridifyMapper that can be null
+ /// optional syntaxTree to Lazy mapping generation
/// type to set mappings
/// return back mapper or new generated mapper if it was null
- public static IGridifyMapper FixMapper(this IGridifyMapper? mapper)
+ private static IGridifyMapper FixMapper(this IGridifyMapper? mapper, SyntaxTree syntaxTree)
{
- return mapper ?? GetDefaultMapper();
+ if (mapper != null) return mapper;
+
+ mapper = new GridifyMapper();
+ foreach (var field in syntaxTree.Root.Descendants()
+ .Where(q => q.Kind == SyntaxKind.FieldExpression)
+ .Cast())
+ {
+ try
+ {
+ mapper.AddMap(field.FieldToken.Text);
+ }
+ catch (Exception)
+ {
+ if (!mapper.Configuration.IgnoreNotMappedFields)
+ throw new GridifyMapperException($"Property '{field.FieldToken.Text}' not found.");
+ }
+ }
+
+ return mapper;
+ }
+
+ private static IEnumerable Descendants(this SyntaxNode root)
+ {
+ var nodes = new Stack(new[] { root });
+ while (nodes.Any())
+ {
+ SyntaxNode node = nodes.Pop();
+ yield return node;
+ foreach (var n in node.GetChildren()) nodes.Push(n);
+ }
}
///
@@ -105,7 +151,6 @@ public static IQueryable ApplyFilteringOrderingPaging(this IQueryable q
IGridifyMapper? mapper = null)
{
if (gridifyQuery == null) return query;
- mapper = mapper.FixMapper();
query = query.ApplyFiltering(gridifyQuery, mapper);
query = query.ApplyOrdering(gridifyQuery, mapper);
@@ -126,7 +171,6 @@ public static IQueryable ApplyOrdering(this IQueryable query, IGridifyO
bool startWithThenBy = false)
{
if (gridifyOrdering == null) return query;
- mapper = mapper.FixMapper();
return string.IsNullOrWhiteSpace(gridifyOrdering.OrderBy)
? query
: ProcessOrdering(query, gridifyOrdering.OrderBy!, startWithThenBy, mapper);
@@ -144,16 +188,50 @@ public static IQueryable ApplyOrdering(this IQueryable query, IGridifyO
public static IQueryable ApplyOrdering(this IQueryable query, string orderBy, IGridifyMapper? mapper = null,
bool startWithThenBy = false)
{
- mapper = mapper.FixMapper();
return string.IsNullOrWhiteSpace(orderBy)
? query
: ProcessOrdering(query, orderBy, startWithThenBy, mapper);
}
- private static IQueryable ProcessOrdering(IQueryable query, string orderings, bool startWithThenBy, IGridifyMapper mapper)
+ public static IQueryable
-
- ..\..\packages\Effort.EF6.2.2.14\lib\net45\Effort.dll
+
+ ..\..\packages\Effort.EF6.2.2.15\lib\net45\Effort.dll
True
diff --git a/test/EntityFramework6IntegrationTests/packages.config b/test/EntityFramework6IntegrationTests/packages.config
index 851ec52b..d639c915 100644
--- a/test/EntityFramework6IntegrationTests/packages.config
+++ b/test/EntityFramework6IntegrationTests/packages.config
@@ -1,6 +1,6 @@
-
+
diff --git a/test/EntityFrameworkIntegrationTests/EntityFrameworkIntegrationTests.cs.csproj b/test/EntityFrameworkIntegrationTests/EntityFrameworkIntegrationTests.cs.csproj
index 257c3ba9..d72bbc58 100644
--- a/test/EntityFrameworkIntegrationTests/EntityFrameworkIntegrationTests.cs.csproj
+++ b/test/EntityFrameworkIntegrationTests/EntityFrameworkIntegrationTests.cs.csproj
@@ -5,8 +5,8 @@
-
-
+
+
diff --git a/test/EntityFrameworkSqlProviderIntegrationTests/EntityFrameworkSqlProviderIntegrationTests.csproj b/test/EntityFrameworkSqlProviderIntegrationTests/EntityFrameworkSqlProviderIntegrationTests.csproj
index 5141bc2d..20605103 100644
--- a/test/EntityFrameworkSqlProviderIntegrationTests/EntityFrameworkSqlProviderIntegrationTests.csproj
+++ b/test/EntityFrameworkSqlProviderIntegrationTests/EntityFrameworkSqlProviderIntegrationTests.csproj
@@ -6,9 +6,9 @@
-
-
-
+
+
+
diff --git a/test/Gridify.Tests/Gridify.Tests.csproj b/test/Gridify.Tests/Gridify.Tests.csproj
index 7ecf3375..e69e49cd 100644
--- a/test/Gridify.Tests/Gridify.Tests.csproj
+++ b/test/Gridify.Tests/Gridify.Tests.csproj
@@ -8,9 +8,12 @@
-
+
-
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+