Skip to content

Commit e508be3

Browse files
authored
Merge pull request #31 from PandaTechAM/development
Add GridifyCursoredQueryModel
2 parents cb5f8fa + a72fd22 commit e508be3

File tree

8 files changed

+388
-296
lines changed

8 files changed

+388
-296
lines changed

Readme.md

Lines changed: 102 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,57 @@
11
# Pandatech.GridifyExtensions
22

3-
Welcome to Pandatech.GridifyExtensions! This library builds on top of the popular Gridify package, adding new
4-
functionalities and simplifying its use for data filtering and pagination in .NET applications.
3+
Welcome to **Pandatech.GridifyExtensions**! This library extends the
4+
powerful [Gridify](https://github.com/alirezanet/Gridify) package, providing additional functionalities and a more
5+
streamlined API for data filtering, ordering, and pagination in .NET applications.
56

6-
## Why Use Pandatech.GridifyExtensions?
7+
## Why Choose Pandatech.GridifyExtensions?
78

8-
Gridify is a powerful tool for querying and filtering data. However, integrating it into your projects can sometimes
9-
involve repetitive code and extra setup. Pandatech.GridifyExtensions aims to make your development process smoother by
10-
offering:
9+
Gridify is great for dynamic querying, but incorporating it into projects can sometimes be repetitive or involve extra
10+
setup. **Pandatech.GridifyExtensions** makes this process more efficient by:
1111

12-
- **Extended Functionality:** Additional methods to handle common data filtering scenarios.
13-
- **Simplified API:** Streamlined usage to minimize boilerplate code and enhance readability.
14-
- **Better Integration:** More intuitive integration with your existing .NET applications.
12+
- **Extending Functionality:** Additional methods to handle common data filtering, ordering, and pagination scenarios.
13+
- **Simplifying the API:** Reducing boilerplate code, making your code cleaner and easier to maintain.
14+
- **Improving Integration:** Seamlessly integrates with .NET and EF Core projects, reducing the overhead of adding
15+
dynamic querying to your applications.
1516

1617
## Features
17-
- **Dynamic Filtering:** Easily apply dynamic filtering to your queries.
18-
- **Dynamic Ordering:** Easily apply dynamic ordering to your queries.
19-
- **Pagination Support:** Simplified methods for paginating your data.
20-
- **Custom Configurations:** Extend and customize Gridify configurations effortlessly.
21-
- **Global Injection:** Inject configurations globally for consistency across your application.
22-
- **Support for Various Data Types:** Handle multiple data types seamlessly.
23-
## Getting Started
24-
To get started, install the package via NuGet:
18+
19+
- **Dynamic Filtering & Ordering:** Easily apply complex filters and ordering to your queries using simple methods.
20+
- **Pagination & Cursor Support:** Paginate data efficiently with support for both traditional pagination and
21+
cursor-based pagination for better scalability.
22+
- **Custom Mappings:** Create custom property mappings for your entities to support advanced querying.
23+
- **Support for Encrypted Fields:** Automatically decrypt values with the provided decryptor function.
24+
- **Aggregation Support:** Perform common aggregate operations like sum, average, min, and max.
25+
26+
## Installation
27+
28+
Install the package via NuGet:
2529

2630
```bash
2731
dotnet add package Pandatech.Gridify.Extensions
2832
```
2933

30-
To enable Gridify support and register custom mapping classes, call the AddGridify method on the WebApplicationBuilder.
31-
You can specify which assemblies to search for configurations.
34+
## Setup
35+
36+
To enable Gridify support and register custom mapping classes, call the `AddGridify` method on the
37+
`WebApplicationBuilder`.
38+
3239
```csharp
3340
builder.AddGridify(params Assembly[] assemblies);
3441
```
3542

43+
You can specify which assemblies to search for configurations. If no assemblies are provided, the current assembly will
44+
be used.
45+
3646
## Usage
37-
**Creating Mappings for Your Entities:**
38-
To efficiently filter and query your Book entity using Gridify, you need to create a mapping class that extends FilterMapper<T>.
39-
This class will define how each property in your Book entity should be mapped.
47+
48+
### Creating Mappings for Your Entities:
49+
50+
To efficiently filter and query your Book entity using Gridify, you need to create a mapping class that extends
51+
`FilterMapper<T>.` This class will define how each property in your entity should be mapped for filtering.
4052

4153
Here’s an example of how to set up the Book entity and its corresponding mapping class:
54+
4255
```csharp
4356
public class Book
4457
{
@@ -56,6 +69,7 @@ public class BookMapper : FilterMapper<Book>
5669
{
5770
public BookMapper()
5871
{
72+
GenerateMappings();
5973
// Map "book-id" to BookId property
6074
AddMap("book-id", x => x.BookId);
6175

@@ -73,68 +87,104 @@ public class BookMapper : FilterMapper<Book>
7387

7488
// Map "other-book-id" to the BookId property of the OtherBook property
7589
AddMap("other-book-id", x => x.OtherBook.BookId);
90+
91+
AddDefaultOrderByDescending("book-id");
7692
}
7793
}
78-
7994
```
8095

81-
Adding Converters
96+
### Adding Converters
8297

83-
You can specify a converter function as the third parameter in the AddMap method to transform the value before it is used.
98+
You can specify a converter function as the third parameter in the AddMap method to transform the value before it is
99+
used.
84100
This is useful for custom data manipulation and formatting.
85101

86-
**Using Extension Methods**
87-
With Pandatech.GridifyExtensions, you can use several extension methods for filtering, sorting, and paging defined on the IQueryable<T> interface. Here are some examples:
88-
Filtering, Sorting, and Paging
89-
90-
Use FilterOrderAndGetPagedAsync to apply filtering, sorting, and paging to your queries:
91102
```csharp
92-
public static async Task<PagedResponse<TDto>> FilterOrderAndGetPagedAsync<TEntity, TDto>(
93-
this IQueryable<TEntity> query, GridifyQueryModel model,
94-
Expression<Func<TEntity, TDto>> selectExpression, CancellationToken cancellationToken = default)
95-
96-
public static Task<PagedResponse<TEntity>> FilterOrderAndGetPagedAsync<TEntity>(
97-
this IQueryable<TEntity> query, GridifyQueryModel model, CancellationToken cancellationToken = default)
103+
public class DeviceFilters : FilterMapper<Device>
104+
{
105+
public DeviceFilters()
106+
{
107+
GenerateMappings();
108+
AddMap("Name", x => x.Name.ToLower(), x => x.ToLower());
109+
AddMap("OsType", x => x.OsType.ToLower(), x => x.ToLower());
110+
AddMap("OsVersion", x => x.OsVersion.ToLower(), x => x.ToLower());
111+
AddMap("BrowserType", x => x.BrowserType.ToLower(), x => x.ToLower());
112+
AddMap("BrowserVersion", x => x.BrowserVersion.ToLower(), x => x.ToLower());
113+
AddMap("UniqueIdPerDevice", x => x.UniqueIdPerDevice.ToLower(), x => x.ToLower());
114+
AddMap("CreatedAt", x => x.CreatedAt, x => x.ToUtcDateTime()); //This is must for date time fields
115+
AddMap("UpdatedAt", x => x.UpdatedAt, x => x.ToUtcDateTime()); //This is must for date time fields
116+
117+
AddDefaultOrderByDescending("Id");
118+
}
119+
}
98120
```
99121

100-
Example Usage:
122+
### Filtering, Sorting, and Paging
123+
124+
Use the `FilterOrderAndGetPagedAsync` method to apply filtering, sorting, and paging to your queries:
125+
101126
```csharp
102127
var pagedResponse = await dbContext.Books
103128
.FilterOrderAndGetPagedAsync(new GridifyQueryModel { PageSize = 10, Page = 1 }, cancellationToken);
104129
```
105130

106-
'GridifyQueryModel' by default has PageSize validation with 500 records. If you want to ignore this validation, you should pass bool 'false' into its constructor, otherwise the validation will be applied into it, and you will not be able to get more records.
131+
Use the `FilterOrderAndGetPagedAsync` method to apply filtering, sorting, and paging to your queries with selected
132+
columns:
133+
134+
```csharp
135+
var pagedBooks = await dbContext.Books
136+
.FilterOrderAndGetPagedAsync(new GridifyQueryModel { Page = 1, PageSize = 10 }, x => new BookDto { Title = x.Title }, cancellationToken);
137+
```
138+
139+
```csharp
140+
141+
**Gridify QueryModel**
142+
143+
By default, `GridifyQueryModel` limits `PageSize` to 500 records. To remove this restriction, initialize it with
144+
`false`:
145+
107146
```csharp
108147
var gridifyQueryModel = new GridifyQueryModel(false) { PageSize = 10, Page = 1 };
109148
```
110149

111-
As an alternative solution you can use 'SetMaxPageSize()' method to set PageSize into 'int.MaxValue' instead of using constructor parameter.
150+
Alternatively, you can set the `PageSize` to the maximum value with:
151+
112152
```csharp
113153
gridifyQueryModel.SetMaxPageSize();
114154
```
115155

116-
Use ColumnDistinctValuesAsync to get distinct values of a specific column:
117-
```csharp
118-
public static async Task<CursoredResponse<object>> ColumnDistinctValuesAsync<TEntity>(
119-
this IQueryable<TEntity> query, ColumnDistinctValueCursoredQueryModel model,
120-
Func<byte[], string>? decryptor = default, CancellationToken cancellationToken = default)
156+
### Cursor-Based Pagination
121157

158+
Use the `FilterOrderAndGetCursoredAsync` method for efficient, scalable cursor-based pagination:
159+
160+
```csharp
161+
var cursoredResponse = await dbContext.Books
162+
.FilterOrderAndGetCursoredAsync(new GridifyCursoredQueryModel { PageSize = 50, Filter="Title>abc"}, cancellationToken);
122163
```
123-
Example Usage:
164+
165+
Use the `FilterOrderAndGetCursoredAsync` method for efficient, scalable cursor-based pagination with selected columns:
166+
124167
```csharp
125-
var distinctValues = await dbContext.Books
126-
.ColumnDistinctValuesAsync(new ColumnDistinctValueCursoredQueryModel { PropertyName = "Title", PageSize=50, Filter="Title>abc" }, cancellationToken);
168+
var cursoredBooks = await dbContext.Books
169+
.FilterOrderAndGetCursoredAsync(new GridifyCursoredQueryModel { PageSize = 50, Filter="Title>abc" }, x => new BookDto { Title = x.Title }, cancellationToken);
127170
```
128171

129-
Use AggregateAsync to perform aggregation operations on your data:
172+
### Distinct Values with Cursors
173+
174+
Get distinct values of a specific column using cursor-based pagination:
175+
130176
```csharp
131-
public static async Task<object> AggregateAsync<TEntity>(
132-
this IQueryable<TEntity> query, AggregateQueryModel model, CancellationToken cancellationToken = default)
177+
var distinctValues = await dbContext.Books
178+
.ColumnDistinctValuesAsync(new ColumnDistinctValueCursoredQueryModel { PropertyName = "Title", PageSize = 50, Filter="Title>abc" }, cancellationToken);
133179
```
134-
Example Usage:
180+
181+
### Aggregation Operations
182+
183+
Perform aggregate operations like sum, average, count, min, and max using `AggregateAsync`:
184+
135185
```csharp
136186
var aggregateResult = await dbContext.Books
137-
.AggregateAsync(new AggregateQueryModel { AggregateType = AggregateType.Sum, PropertyName = "count" }, cancellationToken);
187+
.AggregateAsync(new AggregateQueryModel { AggregateType = AggregateType.Sum, PropertyName = "Count" }, cancellationToken);
138188
```
139189

140190
## License

0 commit comments

Comments
 (0)