diff --git a/PoweredSoft.DynamicQuery.AspNetCore/PoweredSoft.DynamicQuery.AspNetCore.csproj b/PoweredSoft.DynamicQuery.AspNetCore/PoweredSoft.DynamicQuery.AspNetCore.csproj
index 23ccc15..efb4056 100644
--- a/PoweredSoft.DynamicQuery.AspNetCore/PoweredSoft.DynamicQuery.AspNetCore.csproj
+++ b/PoweredSoft.DynamicQuery.AspNetCore/PoweredSoft.DynamicQuery.AspNetCore.csproj
@@ -8,7 +8,7 @@
https://github.com/PoweredSoft/DynamicQuery
github
powered,soft,dynamic,criteria,query,builder,asp,net,core
- 1.0.0$(VersionSuffix)
+ 2.0.0$(VersionSuffix)
https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&r=g&d=retro
PoweredSoft.DynamicQuery.AspNetCore
This projects makes it easier to use dynamic query in a asp.net core mvc project.
diff --git a/PoweredSoft.DynamicQuery.Core/IQueryHandler.cs b/PoweredSoft.DynamicQuery.Core/IQueryHandler.cs
index 4ce5ab2..6a818ff 100644
--- a/PoweredSoft.DynamicQuery.Core/IQueryHandler.cs
+++ b/PoweredSoft.DynamicQuery.Core/IQueryHandler.cs
@@ -19,7 +19,6 @@ namespace PoweredSoft.DynamicQuery.Core
public interface IQueryHandlerAsync : IInterceptableQueryHandler
{
- Task> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default(CancellationToken));
Task> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default(CancellationToken));
Task> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default(CancellationToken));
}
diff --git a/PoweredSoft.DynamicQuery.Core/PoweredSoft.DynamicQuery.Core.csproj b/PoweredSoft.DynamicQuery.Core/PoweredSoft.DynamicQuery.Core.csproj
index 02e5841..cc4ce77 100644
--- a/PoweredSoft.DynamicQuery.Core/PoweredSoft.DynamicQuery.Core.csproj
+++ b/PoweredSoft.DynamicQuery.Core/PoweredSoft.DynamicQuery.Core.csproj
@@ -8,7 +8,7 @@
https://github.com/PoweredSoft/DynamicQuery.Core/
github
powered,soft,dynamic,criteria,query,builder
- 1.0.0$(VersionSuffix)
+ 2.0.0$(VersionSuffix)
https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&r=g&d=retro
PoweredSoft.DynamicQuery.Core
core abstractions
diff --git a/PoweredSoft.DynamicQuery.Test/AsyncTests.cs b/PoweredSoft.DynamicQuery.Test/AsyncTests.cs
index e1915f9..fc74c29 100644
--- a/PoweredSoft.DynamicQuery.Test/AsyncTests.cs
+++ b/PoweredSoft.DynamicQuery.Test/AsyncTests.cs
@@ -1,141 +1,142 @@
-//using PoweredSoft.Data;
-//using PoweredSoft.Data.EntityFrameworkCore;
-//using PoweredSoft.DynamicQuery.Core;
-//using PoweredSoft.DynamicQuery.Test.Mock;
-//using System;
-//using System.Collections.Generic;
-//using System.Linq;
-//using System.Text;
-//using System.Threading.Tasks;
-//using Xunit;
+using PoweredSoft.Data;
+using PoweredSoft.Data.EntityFrameworkCore;
+using PoweredSoft.DynamicQuery.Core;
+using PoweredSoft.DynamicQuery.Extensions;
+using PoweredSoft.DynamicQuery.Test.Mock;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
-//namespace PoweredSoft.DynamicQuery.Test
-//{
-// public class AsyncTests
-// {
-// [Fact]
-// public void TestEmptyCriteria()
-// {
-// MockContextFactory.SeedAndTestContextFor("AsyncTests_TestEmptyCriteria", TestSeeders.SimpleSeedScenario, async ctx =>
-// {
-// var resultShouldMatch = ctx.Items.ToList();
-// var queryable = ctx.Items.AsQueryable();
+namespace PoweredSoft.DynamicQuery.Test
+{
+ public class AsyncTests
+ {
+ [Fact]
+ public void TestEmptyCriteria()
+ {
+ MockContextFactory.SeedAndTestContextFor("AsyncTests_TestEmptyCriteria", TestSeeders.SimpleSeedScenario, async ctx =>
+ {
+ var resultShouldMatch = ctx.Items.ToList();
+ var queryable = ctx.Items.AsQueryable();
-// // query handler that is empty should be the same as running to list.
-// var aqf = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() });
-// var criteria = new QueryCriteria();
-// var queryHandler = new QueryHandlerAsync(aqf);
-// var result = await queryHandler.ExecuteAsync(queryable, criteria);
-// Assert.Equal(resultShouldMatch, result.Data);
-// });
-// }
+ // query handler that is empty should be the same as running to list.
+ var aqf = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() });
+ var criteria = new QueryCriteria();
+ var queryHandler = new QueryHandlerAsync(aqf);
+ var result = await queryHandler.ExecuteAsync(queryable, criteria);
+ Assert.Equal(resultShouldMatch, result.Data);
+ });
+ }
-// [Fact]
-// public void WithGrouping()
-// {
-// MockContextFactory.SeedAndTestContextFor("AsyncTests_WithGrouping", TestSeeders.SimpleSeedScenario, async ctx =>
-// {
-// var shouldResults = ctx.OrderItems
-// .GroupBy(t => t.Order.CustomerId)
-// .Select(t => new
-// {
-// GroupValue = t.Key,
-// Count = t.Count(),
-// ItemQuantityAverage = t.Average(t2 => t2.Quantity),
-// ItemQuantitySum = t.Sum(t2 => t2.Quantity),
-// AvgOfPrice = t.Average(t2 => t2.PriceAtTheTime)
-// })
-// .ToList();
+ [Fact]
+ public void WithGrouping()
+ {
+ MockContextFactory.SeedAndTestContextFor("AsyncTests_WithGrouping", TestSeeders.SimpleSeedScenario, async ctx =>
+ {
+ var shouldResults = ctx.OrderItems
+ .GroupBy(t => t.Order.CustomerId)
+ .Select(t => new
+ {
+ GroupValue = t.Key,
+ Count = t.Count(),
+ ItemQuantityAverage = t.Average(t2 => t2.Quantity),
+ ItemQuantitySum = t.Sum(t2 => t2.Quantity),
+ AvgOfPrice = t.Average(t2 => t2.PriceAtTheTime)
+ })
+ .ToList();
-// // query handler that is empty should be the same as running to list.
-// var criteria = new QueryCriteria()
-// {
-// Groups = new List
-// {
-// new Group { Path = "Order.CustomerId" }
-// },
-// Aggregates = new List
-// {
-// new Aggregate { Type = AggregateType.Count },
-// new Aggregate { Type = AggregateType.Avg, Path = "Quantity" },
-// new Aggregate { Type = AggregateType.Sum, Path = "Quantity" },
-// new Aggregate { Type = AggregateType.Avg, Path = "PriceAtTheTime"}
-// }
-// };
-// var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() });
-// var queryHandler = new QueryHandlerAsync(asyncService);
-// var result = await queryHandler.ExecuteAsync(ctx.OrderItems, criteria);
-// var groups = result.Data.Cast().ToList();
+ // query handler that is empty should be the same as running to list.
+ var criteria = new QueryCriteria()
+ {
+ Groups = new List
+ {
+ new Group { Path = "Order.CustomerId" }
+ },
+ Aggregates = new List
+ {
+ new Aggregate { Type = AggregateType.Count },
+ new Aggregate { Type = AggregateType.Avg, Path = "Quantity" },
+ new Aggregate { Type = AggregateType.Sum, Path = "Quantity" },
+ new Aggregate { Type = AggregateType.Avg, Path = "PriceAtTheTime"}
+ }
+ };
+ var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() });
+ var queryHandler = new QueryHandlerAsync(asyncService);
+ var result = await queryHandler.ExecuteAsync(ctx.OrderItems, criteria);
+ var groups = result.GroupedResult().Groups;
-// // validate group and aggregates of groups.
-// Assert.Equal(groups.Count, shouldResults.Count);
-// Assert.All(groups, g =>
-// {
-// var index = groups.IndexOf(g);
-// var shouldResult = shouldResults[index];
+ // validate group and aggregates of groups.
+ Assert.Equal(groups.Count, shouldResults.Count);
+ Assert.All(groups, g =>
+ {
+ var index = groups.IndexOf(g);
+ var shouldResult = shouldResults[index];
-// // validate the group value.
-// Assert.Equal(g.GroupValue, shouldResult.GroupValue);
+ // validate the group value.
+ Assert.Equal(g.GroupValue, shouldResult.GroupValue);
-// // validate the group aggregates.
-// var aggCount = g.Aggregates.First(t => t.Type == AggregateType.Count);
-// var aggItemQuantityAverage = g.Aggregates.First(t => t.Type == AggregateType.Avg && t.Path == "Quantity");
-// var aggItemQuantitySum = g.Aggregates.First(t => t.Type == AggregateType.Sum && t.Path == "Quantity");
-// var aggAvgOfPrice = g.Aggregates.First(t => t.Type == AggregateType.Avg && t.Path == "PriceAtTheTime");
-// Assert.Equal(shouldResult.Count, aggCount.Value);
-// Assert.Equal(shouldResult.ItemQuantityAverage, aggItemQuantityAverage.Value);
-// Assert.Equal(shouldResult.ItemQuantitySum, aggItemQuantitySum.Value);
-// Assert.Equal(shouldResult.AvgOfPrice, aggAvgOfPrice.Value);
-// });
-// });
-// }
+ // validate the group aggregates.
+ var aggCount = g.Aggregates.First(t => t.Type == AggregateType.Count);
+ var aggItemQuantityAverage = g.Aggregates.First(t => t.Type == AggregateType.Avg && t.Path == "Quantity");
+ var aggItemQuantitySum = g.Aggregates.First(t => t.Type == AggregateType.Sum && t.Path == "Quantity");
+ var aggAvgOfPrice = g.Aggregates.First(t => t.Type == AggregateType.Avg && t.Path == "PriceAtTheTime");
+ Assert.Equal(shouldResult.Count, aggCount.Value);
+ Assert.Equal(shouldResult.ItemQuantityAverage, aggItemQuantityAverage.Value);
+ Assert.Equal(shouldResult.ItemQuantitySum, aggItemQuantitySum.Value);
+ Assert.Equal(shouldResult.AvgOfPrice, aggAvgOfPrice.Value);
+ });
+ });
+ }
-// [Fact]
-// public void SimpleFilter()
-// {
-// MockContextFactory.SeedAndTestContextFor("AsyncTests_SimpleFilter", TestSeeders.SimpleSeedScenario, async ctx =>
-// {
-// var resultShouldMatch = ctx.Items.Where(t => t.Name.EndsWith("Cables")).ToList();
+ [Fact]
+ public void SimpleFilter()
+ {
+ MockContextFactory.SeedAndTestContextFor("AsyncTests_SimpleFilter", TestSeeders.SimpleSeedScenario, async ctx =>
+ {
+ var resultShouldMatch = ctx.Items.Where(t => t.Name.EndsWith("Cables")).ToList();
-// var criteria = new QueryCriteria()
-// {
-// Filters = new List
-// {
-// new SimpleFilter
-// {
-// Path = "Name",
-// Type = FilterType.EndsWith,
-// Value = "Cables"
-// }
-// }
-// };
+ var criteria = new QueryCriteria()
+ {
+ Filters = new List
+ {
+ new SimpleFilter
+ {
+ Path = "Name",
+ Type = FilterType.EndsWith,
+ Value = "Cables"
+ }
+ }
+ };
-// var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() });
-// var queryHandler = new QueryHandlerAsync(asyncService);
-// var result = await queryHandler.ExecuteAsync(ctx.Items, criteria);
-// Assert.Equal(resultShouldMatch, result.Data);
-// });
-// }
+ var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() });
+ var queryHandler = new QueryHandlerAsync(asyncService);
+ var result = await queryHandler.ExecuteAsync(ctx.Items, criteria);
+ Assert.Equal(resultShouldMatch, result.Data);
+ });
+ }
-// [Fact]
-// public void TestPaging()
-// {
-// MockContextFactory.SeedAndTestContextFor("AsyncTests_TestPagging", TestSeeders.SimpleSeedScenario, async ctx =>
-// {
-// var resultShouldMatch = ctx.OrderItems.OrderBy(t => t.Id).Skip(5).Take(5).ToList();
+ [Fact]
+ public void TestPaging()
+ {
+ MockContextFactory.SeedAndTestContextFor("AsyncTests_TestPagging", TestSeeders.SimpleSeedScenario, async ctx =>
+ {
+ var resultShouldMatch = ctx.OrderItems.OrderBy(t => t.Id).Skip(5).Take(5).ToList();
-// // query handler that is empty should be the same as running to list.
-// var criteria = new QueryCriteria();
-// criteria.Sorts.Add(new Sort("Id"));
-// criteria.Page = 2;
-// criteria.PageSize = 5;
+ // query handler that is empty should be the same as running to list.
+ var criteria = new QueryCriteria();
+ criteria.Sorts.Add(new Sort("Id"));
+ criteria.Page = 2;
+ criteria.PageSize = 5;
-// var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() });
-// var queryHandler = new QueryHandlerAsync(asyncService);
-// var result = await queryHandler.ExecuteAsync(ctx.OrderItems, criteria);
-// Assert.Equal(resultShouldMatch, result.Data);
-// });
-// }
-// }
+ var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() });
+ var queryHandler = new QueryHandlerAsync(asyncService);
+ var result = await queryHandler.ExecuteAsync(ctx.OrderItems, criteria);
+ Assert.Equal(resultShouldMatch, result.Data);
+ });
+ }
+ }
-//}
+}
diff --git a/PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj b/PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj
index aefa7bb..c7bb118 100644
--- a/PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj
+++ b/PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj
@@ -8,7 +8,7 @@
https://github.com/PoweredSoft/DynamicQuery
github
powered,soft,dynamic,criteria,query,builder
- 1.0.0$(VersionSuffix)
+ 2.0.0$(VersionSuffix)
https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&r=g&d=retro
PoweredSoft.DynamicQuery
dynamic query based on string path very usefull for network requests.
diff --git a/PoweredSoft.DynamicQuery/QueryHandler.cs b/PoweredSoft.DynamicQuery/QueryHandler.cs
index ecccdb6..bff122a 100644
--- a/PoweredSoft.DynamicQuery/QueryHandler.cs
+++ b/PoweredSoft.DynamicQuery/QueryHandler.cs
@@ -22,7 +22,7 @@ namespace PoweredSoft.DynamicQuery
protected virtual IQueryExecutionResult ExecuteGrouping()
{
- var result = new QueryGroupExecutionResult();
+ var result = new QueryExecutionGroupResult();
// preserve queryable.
var queryableAfterFilters = CurrentQueryable;
diff --git a/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs b/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs
index d2a6771..9ffe598 100644
--- a/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs
+++ b/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs
@@ -3,61 +3,52 @@ using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
+using PoweredSoft.Data;
using PoweredSoft.Data.Core;
using PoweredSoft.DynamicLinq;
using PoweredSoft.DynamicQuery.Core;
namespace PoweredSoft.DynamicQuery
{
- /*
+
public class QueryHandlerAsync : QueryHandlerBase, IQueryHandlerAsync
{
- internal MethodInfo ExecuteAsyncGeneric = typeof(QueryHandlerAsync).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic).First(t => t.Name == "ExecuteAsync" && t.IsGenericMethod);
-
public IAsyncQueryableService AsyncQueryableService { get; }
- internal Task ExecuteAsyncReflected(CancellationToken cancellationToken) => (Task)ExecuteAsyncGeneric.MakeGenericMethod(QueryableUnderlyingType).Invoke(this, new object[] { cancellationToken });
-
public QueryHandlerAsync(IAsyncQueryableService asyncQueryableService)
{
AsyncQueryableService = asyncQueryableService;
}
- protected virtual Task ExecuteAsync(CancellationToken cancellationToken = default(CancellationToken))
+ protected virtual Task> FinalExecuteAsync(CancellationToken cancellationToken = default(CancellationToken))
{
- CommonBeforeExecute();
- return HasGrouping ? ExecuteAsyncGrouping(cancellationToken) : ExecuteAsyncNoGrouping(cancellationToken);
+ CommonBeforeExecute();
+ return HasGrouping ? ExecuteAsyncGrouping(cancellationToken) : ExecuteAsyncNoGrouping(cancellationToken);
}
- public Task ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default(CancellationToken))
+ protected virtual async Task> ExecuteAsyncGrouping(CancellationToken cancellationToken)
{
- Reset(queryable, criteria);
- return ExecuteAsyncReflected(cancellationToken);
- }
-
- protected virtual async Task ExecuteAsyncGrouping(CancellationToken cancellationToken)
- {
- var result = new QueryExecutionResult();
+ var result = new QueryExecutionGroupResult();
// preserve queryable.
var queryableAfterFilters = CurrentQueryable;
// async.
- result.TotalRecords = await this.AsyncQueryableService.LongCountAsync((IQueryable)queryableAfterFilters, cancellationToken);
+ result.TotalRecords = await this.AsyncQueryableService.LongCountAsync((IQueryable)queryableAfterFilters, cancellationToken);
CalculatePageCount(result);
// intercept groups in advance to avoid doing it more than once :)
- var finalGroups = Criteria.Groups.Select(g => InterceptGroup(g)).ToList();
+ var finalGroups = Criteria.Groups.Select(g => InterceptGroup(g)).ToList();
// get the aggregates.
- var aggregateResults = await FetchAggregatesAsync(finalGroups, cancellationToken);
+ var aggregateResults = await FetchAggregatesAsync(finalGroups, cancellationToken);
// sorting.
finalGroups.ForEach(fg => Criteria.Sorts.Insert(0, new Sort(fg.Path, fg.Ascending)));
// apply sorting and paging.
- ApplySorting();
- ApplyPaging();
+ ApplySorting();
+ ApplyPaging();
// create group & select expression.
CurrentQueryable = CurrentQueryable.GroupBy(QueryableUnderlyingType, gb => finalGroups.ForEach((fg, index) => gb.Path(fg.Path, $"Key_{index}")));
@@ -71,52 +62,52 @@ namespace PoweredSoft.DynamicQuery
var groupRecords = await AsyncQueryableService.ToListAsync(CurrentQueryable.Cast(), cancellationToken);
// now join them into logical collections
- var lastLists = new List>();
- result.Data = RecursiveRegroup(groupRecords, aggregateResults, Criteria.Groups.First(), lastLists);
+ var lastLists = new List<(List entities, IGroupQueryResult group)>();
+ result.Groups = RecursiveRegroup(groupRecords, aggregateResults, Criteria.Groups.First(), lastLists);
// converted to grouped by.
- await QueryInterceptToGrouped(lastLists);
+ await QueryInterceptToGrouped(lastLists);
- result.Aggregates = await CalculateTotalAggregateAsync(queryableAfterFilters, cancellationToken);
+ result.Aggregates = await CalculateTotalAggregateAsync(queryableAfterFilters, cancellationToken);
return result;
}
- protected async Task ExecuteAsyncNoGrouping(CancellationToken cancellationToken)
+ protected async Task> ExecuteAsyncNoGrouping(CancellationToken cancellationToken)
{
- var result = new QueryExecutionResult();
+ var result = new QueryExecutionResult();
// after filter queryable
- IQueryable afterFilterQueryable = (IQueryable)CurrentQueryable;
+ IQueryable afterFilterQueryable = (IQueryable)CurrentQueryable;
// total records.
result.TotalRecords = await AsyncQueryableService.LongCountAsync(afterFilterQueryable, cancellationToken);
CalculatePageCount(result);
// sorts and paging.
- ApplySorting();
- ApplyPaging();
+ ApplySorting();
+ ApplyPaging();
// data.
- var entities = await AsyncQueryableService.ToListAsync(((IQueryable)CurrentQueryable), cancellationToken);
- var records = await InterceptConvertTo(entities);
+ var entities = await AsyncQueryableService.ToListAsync(((IQueryable)CurrentQueryable), cancellationToken);
+ var records = await InterceptConvertTo(entities);
result.Data = records;
// aggregates.
- result.Aggregates = await CalculateTotalAggregateAsync(afterFilterQueryable, cancellationToken);
+ result.Aggregates = await CalculateTotalAggregateAsync(afterFilterQueryable, cancellationToken);
return result;
}
- protected virtual async Task> CalculateTotalAggregateAsync(IQueryable queryableAfterFilters, CancellationToken cancellationToken)
+ protected virtual async Task> CalculateTotalAggregateAsync(IQueryable queryableAfterFilters, CancellationToken cancellationToken)
{
if (!Criteria.Aggregates.Any())
return null;
- IQueryable selectExpression = CreateTotalAggregateSelectExpression(queryableAfterFilters);
+ IQueryable selectExpression = CreateTotalAggregateSelectExpression(queryableAfterFilters);
var aggregateResult = await AsyncQueryableService.FirstOrDefaultAsync(selectExpression.Cast());
return MaterializeCalculateTotalAggregateResult(aggregateResult);
}
- protected async virtual Task>> FetchAggregatesAsync(List finalGroups, CancellationToken cancellationToken)
+ protected async virtual Task>> FetchAggregatesAsync(List finalGroups, CancellationToken cancellationToken)
{
if (!Criteria.Aggregates.Any())
return null;
@@ -125,7 +116,7 @@ namespace PoweredSoft.DynamicQuery
var whenAllResult = await Task.WhenAll(finalGroups.Select(fg =>
{
- IQueryable selectExpression = CreateFetchAggregateSelectExpression(fg, previousGroups);
+ IQueryable selectExpression = CreateFetchAggregateSelectExpression(fg, previousGroups);
var selectExpressionCasted = selectExpression.Cast();
var aggregateResult = AsyncQueryableService.ToListAsync(selectExpressionCasted, cancellationToken);
previousGroups.Add(fg);
@@ -135,5 +126,17 @@ namespace PoweredSoft.DynamicQuery
var finalResult = whenAllResult.ToList();
return finalResult;
}
- }*/
+
+ public Task> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ Reset(queryable, criteria);
+ return FinalExecuteAsync(cancellationToken);
+ }
+
+ public Task> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ Reset(queryable, criteria);
+ return FinalExecuteAsync(cancellationToken);
+ }
+ }
}
diff --git a/PoweredSoft.DynamicQuery/QueryResult.cs b/PoweredSoft.DynamicQuery/QueryResult.cs
index 89a3cb1..a8ffc14 100644
--- a/PoweredSoft.DynamicQuery/QueryResult.cs
+++ b/PoweredSoft.DynamicQuery/QueryResult.cs
@@ -34,7 +34,7 @@ namespace PoweredSoft.DynamicQuery
public long? NumberOfPages { get; set; }
}
- public class QueryGroupExecutionResult : QueryExecutionResult, IQueryExecutionGroupResult
+ public class QueryExecutionGroupResult : QueryExecutionResult, IQueryExecutionGroupResult
{
public List> Groups { get; set; }
}