- Create entity
public class Entity
{
public long Id { get; set; }
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
public int Height { get; set; }
public int Weight { get; set; }
}
- Create sorting configuration class. Inherit it from the ISortingConfiguration<T> interface
public class EntitySortingConfiguration : ISortingConfiguration<Entity>
{
public void Configure(ISortingConfigurationBuilder<Entity> builder)
{
builder
.RuleFor("Id", x => x.Id)
.RuleFor("Name", x => x.Name)
.RuleFor("Age", x => x.Age)
.RuleFor("Height", x => x.Height)
.RuleFor("Weight", x => x.Weight);
}
}
- Call the extension method
AddSmartSorter(this IServiceCollection serviceCollection, Action<SortingConfigurationOptions> optionsBuilder)
and pass the assembly for scanning configurations
var serviceProvider = new ServiceCollection()
.AddSmartSorter(options => options.AddAssembly(Assembly.GetExecutingAssembly()))
.BuildServiceProvider();
- Get the
IConfigurationProvider
interface as dependency
configurationProvider = serviceProvider.GetRequiredService<IConfigurationProvider>()
- Use the extension method
ApplySorting<TSource>(this IQueryable<TSource> source, IConfigurationProvider configurationProvider, SortingRules sortingRules)
to apply sorting rules to your query
var sortingRules = new(new Dictionary<string, SortDirection>
{
["Name"] = SortDirection.Descending,
["Age"] = SortDirection.Ascending,
["Id"] = SortDirection.Descending
})
var sortedEntities = await _testContext
.Entities
.ApplySorting(configurationProvider, sortingRules)
.ToListAsync(cancellationToken)
[MemoryDiagnoser]
public class Benchmark : IDisposable, IAsyncDisposable
{
...
private readonly SortingRules _sortingRules = new(new Dictionary<string, SortDirection>
{
["Name"] = SortDirection.Descending,
["Age"] = SortDirection.Ascending,
["Id"] = SortDirection.Descending
});
...
[Benchmark]
public string SmartSorter()
{
return _testContext
.Entities
.ApplySorting(_configurationProvider, _sortingRules)
.ToQueryString();
}
[Benchmark(Baseline = true)]
public string DefaultOrderBy()
{
return _testContext
.Entities
.OrderByDescending(x => x.Name)
.ThenBy(x => x.Age)
.ThenByDescending(x => x.Id)
.ToQueryString();
}
...
}
Environment
BenchmarkDotNet v0.13.9+228a464e8be6c580ad9408e98f18813f6407fb5a, Windows 10 (10.0.19045.3516/22H2/2022Update) Intel Core i5-8500 CPU 3.00GHz (Coffee Lake), 1 CPU, 6 logical and 6 physical cores .NET SDK 7.0.304 [Host] : .NET 6.0.1 (6.0.121.56705), X64 RyuJIT AVX2 DefaultJob : .NET 6.0.1 (6.0.121.56705), X64 RyuJIT AVX2
Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|
SmartSorter | 26.45 us | 0.137 us | 0.114 us | 0.93 | 1.5564 | 7.17 KB | 0.91 |
DefaultOrderBy | 28.61 us | 0.213 us | 0.200 us | 1.00 | 1.6785 | 7.84 KB | 1.00 |