Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

### V3.1.2 (2022/07/14)

-[#22](https://github.com/linmasaki/KendoNET.DynamicLinq/discussions/22) Rename this repository.
-[#22](https://github.com/luizfbicalho/KendoNET.DynamicLinq/discussions/22) Rename this repository.

### V3.1.1 (2020/11/05)

- [#13](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/13) Fix the issue that filter will throw exception if decimal property is optional.
- [#6](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/6) Add asynchronous method of retrieving data(This feature is still in the experimental stage, not recommend using it on your product).
- [#13](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/13) Fix the issue that filter will throw exception if decimal property is optional.
- [#6](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/6) Add asynchronous method of retrieving data(This feature is still in the experimental stage, not recommend using it on your product).

### V3.1.0 (2020/02/11)

- [#10](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/10) Fix the issue that the LINQ query with sub-property can't be translated and will be evaluated locally.
- [#12](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/12) Amend the issue that the method `ToDataSourceResult<T>(this IQueryable<T> queryable, DataSourceRequest request)` would ignore the
- [#10](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/10) Fix the issue that the LINQ query with sub-property can't be translated and will be evaluated locally.
- [#12](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/12) Amend the issue that the method `ToDataSourceResult<T>(this IQueryable<T> queryable, DataSourceRequest request)` would ignore the
aggregator parameter.

### V2.2.2 (2019/09/17)
Expand All @@ -23,13 +23,13 @@
### V2.2.0 (2019/07/05)

- Change the property `Group` of DataSourceResult to `Groups`.
- [#5](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/5) Add new property `Aggregate` to DataSourceRequest.
- [#5](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/5) Fixed getting wrong grouping data in the request using aggregates in grouping configuration.
- [#5](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/5) Add new property `Aggregate` to DataSourceRequest.
- [#5](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/5) Fixed getting wrong grouping data in the request using aggregates in grouping configuration.

### V2.1.0 (2019/05/16)

- [#3](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/3) Support new filtering operators of `is null`, `is not null`, `is empty`, `is not empty`, `has value`, and `has no value` in grid.
- [#3](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/3) Filtering operators of `is empty`, `is not empty`, `has value`, and `has no value` doesn't support non-string types.
- [#3](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/3) Support new filtering operators of `is null`, `is not null`, `is empty`, `is not empty`, `has value`, and `has no value` in grid.
- [#3](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/3) Filtering operators of `is empty`, `is not empty`, `has value`, and `has no value` doesn't support non-string types.

### V2.0.2 (2019/04/12)

Expand All @@ -41,8 +41,8 @@

### V2.0.0 (2018/09/10)

- [#2](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/2) Support .Net Standard 2.0.
- [#2](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/2) Support .Net Standard 2.0.

### V1.0.3 (2017/02/069)

- [#1](https://github.com/linmasaki/KendoNET.DynamicLinq/issues/1) Add `Errors` property in **`DataSourceResult`** class.
- [#1](https://github.com/luizfbicalho/KendoNET.DynamicLinq/issues/1) Add `Errors` property in **`DataSourceResult`** class.
55 changes: 55 additions & 0 deletions KendoNET.DynamicLinq.EFCore/KendoNET.DynamicLinq.EFCore.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\KendoNET.DynamicLinq.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AsyncFixer" Version="1.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.0-preview.25258.110">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="nerdbank.gitversioning" Version="3.8.38-alpha">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Nullable.Extended.Analyzer" Version="1.15.6581">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Analyzers" Version="4.13.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.10.0.116381">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Tetractic.CodeAnalysis.ExceptionAnalyzers" Version="1.4.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
150 changes: 150 additions & 0 deletions KendoNET.DynamicLinq.EFCore/QueryableAsyncExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace KendoNET.DynamicLinq.EFCore
{
/// <summary>
/// Provides extension methods for asynchronously applying Kendo-style data operations (paging, sorting, filtering, grouping, and aggregation)
/// to <see cref="IQueryable{T}"/> sources using Dynamic LINQ and Entity Framework Core.
/// </summary>
public static class QueryableAsyncExtensionsAsync
{
/// <summary>
/// Applies data processing (paging, sorting and filtering) over IQueryable using Dynamic Linq.
/// </summary>
/// <typeparam name="T">The type of the IQueryable.</typeparam>
/// <param name="queryable">The IQueryable which should be processed.</param>
/// <param name="take">Specifies how many items to take. Configurable via the pageSize setting of the Kendo DataSource.</param>
/// <param name="skip">Specifies how many items to skip.</param>
/// <param name="sort">Specifies the current sort order.</param>
/// <param name="filter">Specifies the current filter.</param>
/// <param name="ct"></param>
/// <returns>A DataSourceResult object populated from the processed IQueryable.</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="AmbiguousMatchException"></exception>
/// <exception cref="NotSupportedException"></exception>
/// <exception cref="TargetInvocationException"></exception>
/// <exception cref="MethodAccessException"></exception>
/// <exception cref="MemberAccessException"></exception>
/// <exception cref="System.Runtime.InteropServices.InvalidComObjectException"></exception>
/// <exception cref="System.Runtime.InteropServices.COMException"></exception>
/// <exception cref="TypeLoadException"></exception>
/// <exception cref="InvalidOperationException"></exception>
/// <exception cref="TargetException"></exception>
/// <exception cref="TargetParameterCountException"></exception>
/// <exception cref="OverflowException"></exception>
/// <exception cref="OutOfMemoryException"></exception>
/// <exception cref="OperationCanceledException"></exception>
public static Task<DataSourceResult<T>> ToDataSourceResultAsync<T>(this IQueryable<T> queryable, int take, int skip, IEnumerable<Sort> sort, Filter filter, CancellationToken ct)
{
return queryable.ToDataSourceResultAsync(take, skip, sort, filter, null, null, ct);
}

/// <summary>
/// Applies data processing (paging, sorting and filtering) over IQueryable using Dynamic Linq.
/// </summary>
/// <typeparam name="T">The type of the IQueryable.</typeparam>
/// <param name="queryable">The IQueryable which should be processed.</param>
/// <param name="request">The DataSourceRequest object containing take, skip, sort, filter, aggregates, and groups data.</param>
/// <param name="ct"></param>
/// <returns>A DataSourceResult object populated from the processed IQueryable.</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="AmbiguousMatchException"></exception>
/// <exception cref="NotSupportedException"></exception>
/// <exception cref="TargetInvocationException"></exception>
/// <exception cref="MethodAccessException"></exception>
/// <exception cref="MemberAccessException"></exception>
/// <exception cref="System.Runtime.InteropServices.InvalidComObjectException"></exception>
/// <exception cref="System.Runtime.InteropServices.COMException"></exception>
/// <exception cref="TypeLoadException"></exception>
/// <exception cref="InvalidOperationException"></exception>
/// <exception cref="TargetException"></exception>
/// <exception cref="TargetParameterCountException"></exception>
/// <exception cref="OverflowException"></exception>
/// <exception cref="OutOfMemoryException"></exception>
/// <exception cref="OperationCanceledException"></exception>
public static Task<DataSourceResult<T>> ToDataSourceResultAsync<T>(this IQueryable<T> queryable, DataSourceRequest request, CancellationToken ct)
{
return queryable.ToDataSourceResultAsync(request.Take, request.Skip, request.Sort, request.Filter, request.Aggregate, request.Group, ct);
}

/// <summary>
/// Applies data processing (paging, sorting, filtering and aggregates) over IQueryable using Dynamic Linq.
/// </summary>
/// <typeparam name="T">The type of the IQueryable.</typeparam>
/// <param name="queryable">The IQueryable which should be processed.</param>
/// <param name="take">Specifies how many items to take. Configurable via the pageSize setting of the Kendo DataSource.</param>
/// <param name="skip">Specifies how many items to skip.</param>
/// <param name="sort">Specifies the current sort order.</param>
/// <param name="filter">Specifies the current filter.</param>
/// <param name="aggregates">Specifies the current aggregates.</param>
/// <param name="group">Specifies the current groups.</param>
/// <param name="ct"></param>
/// <returns>A DataSourceResult object populated from the processed IQueryable.</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="AmbiguousMatchException"></exception>
/// <exception cref="NotSupportedException"></exception>
/// <exception cref="TargetInvocationException"></exception>
/// <exception cref="MethodAccessException"></exception>
/// <exception cref="MemberAccessException"></exception>
/// <exception cref="System.Runtime.InteropServices.InvalidComObjectException"></exception>
/// <exception cref="System.Runtime.InteropServices.COMException"></exception>
/// <exception cref="TypeLoadException"></exception>
/// <exception cref="InvalidOperationException"></exception>
/// <exception cref="TargetException"></exception>
/// <exception cref="TargetParameterCountException"></exception>
/// <exception cref="OverflowException"></exception>
/// <exception cref="OutOfMemoryException"></exception>
/// <exception cref="OperationCanceledException"></exception>
public static async Task<DataSourceResult<T>> ToDataSourceResultAsync<T>(this IQueryable<T> queryable,
int take,
int skip,
IEnumerable<Sort> sort,
Filter? filter,
IEnumerable<Aggregator>? aggregates,
IEnumerable<Group>? group,
CancellationToken ct)
{
var errors = new List<object>();

// Filter the data first
queryable = queryable.Filters(filter, errors);

// Calculate the total number of records (needed for paging)
var total = await queryable.CountAsync(ct);

// Calculate the aggregates
var aggregate = queryable.Aggregates(aggregates);
queryable = queryable.UpdateQuery(take, skip, sort, group);

var result = new DataSourceResult<T>
{
Total = total,
Aggregates = aggregate
};

// Group By
if (group?.Any() == true)
{
result.Groups = await queryable.GroupByMany(group).AsQueryable().ToListAsync(ct);
}
else
{
result.Data = await queryable.ToListAsync(ct);
}

// Set errors if any
if (errors.Count > 0)
{
result.Errors = errors;
}

return result;
}
}
}
20 changes: 17 additions & 3 deletions KendoNET.DynamicLinq.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29609.76
# Visual Studio Version 17
VisualStudioVersion = 17.14.36121.58 d17.14
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KendoNET.DynamicLinq", "src\KendoNET.DynamicLinq.csproj", "{6F75D7FE-0A2C-4586-8152-D25AA61E6CA9}"
EndProject
Expand All @@ -17,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Assets", "Assets", "{531E0E
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KendoNET.DynamicLinq.EFCore", "KendoNET.DynamicLinq.EFCore\KendoNET.DynamicLinq.EFCore.csproj", "{E71AD039-BF32-48A0-8BA7-14AA09082B52}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -63,11 +65,23 @@ Global
{E3FA5C13-FD73-457B-85F2-30D8BA0CCA82}.Release|x64.Build.0 = Release|Any CPU
{E3FA5C13-FD73-457B-85F2-30D8BA0CCA82}.Release|x86.ActiveCfg = Release|Any CPU
{E3FA5C13-FD73-457B-85F2-30D8BA0CCA82}.Release|x86.Build.0 = Release|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Debug|x64.ActiveCfg = Debug|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Debug|x64.Build.0 = Debug|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Debug|x86.ActiveCfg = Debug|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Debug|x86.Build.0 = Debug|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Release|Any CPU.Build.0 = Release|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Release|x64.ActiveCfg = Release|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Release|x64.Build.0 = Release|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Release|x86.ActiveCfg = Release|Any CPU
{E71AD039-BF32-48A0-8BA7-14AA09082B52}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E645F9BA-8510-4B50-98F7-3740F27727CB}
EndGlobalSection
EndGlobal
EndGlobal
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 CoCo Lin
Copyright (c) 2019 luiz bicalho

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@

[![Version](https://img.shields.io/nuget/vpre/KendoNET.DynamicLinq.svg)](https://www.nuget.org/packages/KendoNET.DynamicLinq)
[![Downloads](https://img.shields.io/nuget/dt/KendoNET.DynamicLinq.svg)](https://www.nuget.org/packages/KendoNET.DynamicLinq)
[![.NET Standard](https://img.shields.io/badge/.NET%20Standard-%3E%3D%201.6-red.svg)](#)
[![.NET 8.0](https://img.shields.io/badge/.NET-8.0-red)](#)

## Description

KendoNET.DynamicLinq implements server paging, filtering, sorting, grouping, and aggregating to Kendo UI via Dynamic Linq for .Net Core App(1.x ~ 3.x).
KendoNET.DynamicLinq implements server paging, filtering, sorting, grouping, and aggregating to Kendo UI via Dynamic Linq for .Net 8.

## Prerequisites

### .Net Core 1 ~ 2
### .Net 8 Newtonsoft.Json

- None

### .Net Core 3
### .Net 8 System.Text.Json

- You must add custom `ObjectToInferredTypesConverter` to your `JsonSerializerOptions` since `System.Text.Json` didn't deserialize inferred type to object properties now, see
the [sample code](https://github.com/linmasaki/KendoNET.DynamicLinq/blob/master/test/KendoNET.DynamicLinq.Tests/CustomJsonSerializerOptions.cs)
the [sample code](https://github.com/luizfbicalho/KendoNET.DynamicLinq/blob/master/test/KendoNET.DynamicLinq.Tests/CustomJsonSerializerOptions.cs)
and [reference](https://docs.microsoft.com/en-gb/dotnet/standard/serialization/system-text-json-converters-how-to#deserialize-inferred-types-to-object-properties).

## Usage
Expand Down Expand Up @@ -165,7 +165,7 @@ public class MyContext : DbContext
2. Switch to project root directory(src\KendoNET.DynamicLinq).
3. Run "dotnet restore"
4. Run "dotnet pack --configuration Release"
5. Add `<repository type="git" url="https://github.com/linmasaki/KendoNET.DynamicLinq.git" />` to package metadata of nupkg to show repository URL at Nuget
5. Add `<repository type="git" url="https://github.com/luizfbicalho/KendoNET.DynamicLinq.git" />` to package metadata of nupkg to show repository URL at Nuget

## Note

Expand Down
Loading