I have found an error when the grid is loading data by Ajax with grouping in Asp.net core 6.0 and EF core 6.0 in versión.
I am using the version Telerik.UI.for.AspNet.Core 2022.1.412.
The method Kendo.Mvc.Extensions.QueryableExtensions.ToDataSourceResult is not able to perform the query when DataSourceRequest have included a grouping.
Now, I am going to write down some code to facilating the compressino of issue
The classes in the model uses to load the grid are:
public class TipoVia
{
public Guid Id {get; set;}
public string Codigo {get; set;}
public string Descripcion {get; set;}
}
public class DataContext : DbContext
{
public DbSet<TipoVia> TiposVia { get; set; }
}
In the view the telerik grid is configured with Ajax the next way:
@Html.Kendo().Grid<TipoVia>.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.Codigo);
columns.Bound(p => p.Descripcion);
}
.DataSource(dataSource =>
dataSource.Ajax().PageSize(10)
.Read(read => read.Action("GetData", "ControllerTipoVia").Data("obtenerModel").Type(HttpVerbs.Post))
);
In the controller the method that It does the loading is:
public virtual Task<IActionResult> ObtenerPaginaKendo([DataSourceRequest]DataSourceRequest request, TConsultaViewModel viewModelVista)
{
var dsResult = viewModelVista.DataContext.TiposVia.ToDataSourceResult(request);
return Task.Run<IActionResult>(() => Json(dsResult));
}
Finally, if It is grouped by TipoVia.Codigo the error is the next:
System.InvalidOperationException
HResult=0x80131509
Mensaje = The LINQ expression 'DbSet<TipoVia>()
.OrderBy(c => c.Nombre)
.Select(entidad => new {
Codigo = entidad.Codigo,
Nombre = entidad.Descripcion
}
)
.OrderBy(item => item.Codigo)
.Skip(__p_0)
.Take(__p_1)
.GroupBy(item => item.Codigo)
.OrderBy(group1509060 => group1509060.Key)
.Select(group1509060 => new AggregateFunctionsGroup{
Key = group1509060.Key,
ItemCount = group1509060
.AsQueryable()
.Count(),
HasSubgroups = False,
Member = "Codigo",
Items = group1509060
}
)' could not be translated. Additional information: Translation of 'Select' which contains grouping parameter without composition is not supported. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Origen = Microsoft.EntityFrameworkCore
Seguimiento de la pila:
en Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
en Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.Expand(Expression query)
en Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query)
en Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
en Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
en Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
en Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
en Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
en Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
en Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.System.Collections.IEnumerable.GetEnumerator()
en Kendo.Mvc.Extensions.QueryableExtensions.Execute[TModel,TResult](IQueryable source, Func`2 selector)
en Kendo.Mvc.Extensions.QueryableExtensions.CreateDataSourceResult[TModel,TResult](IQueryable queryable, DataSourceRequest request, ModelStateDictionary modelState, Func`2 selector)
en Kendo.Mvc.Extensions.QueryableExtensions.ToDataSourceResult(IQueryable queryable, DataSourceRequest request, ModelStateDictionary modelState)
en Kendo.Mvc.Extensions.QueryableExtensions.ToDataSourceResult(IQueryable queryable, DataSourceRequest request)
en GiaBase.AspMvc.Controllers.ConsultaController`5.ObtenerPaginaKendo(DataSourceRequest request, TConsultaViewModel viewModelVista) en C:\Users\U178476\Documents\Repo\comun\codigo\GiaBase\src\GiaBase.AspMvc\Controllers\ConsultaController.cs: línea 419
en Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.<Execute>d__0.MoveNext()
2 Answers, 1 is accepted
Hello Agustin,
Thank you for sharing the details on reproducing the issue. In general, the ToDataSourceResult method takes the information on paging, sorting, grouping, etc from the DataSourceRequest object and translates it to a LINQ query. Inspecting the error message I have found this EF Core issue and the parent one summing up issues with using the GroupBy. Based on the details provided this seems to be an EF Core issue rather than related to the use of the ToDataSourceResult method.
Regards,
Aleksandar
Progress Telerik
Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.
Hello Aleksandar
I believe It will be an issues of Ef Core, but ToDataSourceResult is a method of Kendo library uses to configure grouping, sorting ... that it must work correctly despite the new way to do queries with LINQ.
Will it fixed in a future?
Regards,
Agustin
The ToDataSourceResult is indeed a Telerik UI for ASP.NET Core method, but the library itself is also dependent on other libraries. Try running the shared LINQ statement as a standalone query and note if the same error will occur. If so, then this will indeed be a EF Core related issue and as such is outside of our scope. The DataSourceRequest object contains information on the request, so you may consider re-writing the query yourself so the data is fetched. This SO post has a suggestion on how the query in the EF Core issue can be re-written, to avoid the behavior. You can then follow the example in the Custom Ajax Binding Demo for the Grid on how to return the data to the Grid.
If running the LINQ query as a standalone query does not error out, and the error occurs only when using the ToDataSourceResult method consider providing a runnable sample app, where this can be observed. You can submit a support ticket or post to this thread, as you desire. This way we can investigate further.
Hello Aleksandar,
I understand your remark about this being an issue outside the ToDataSourceResult. I've also read the EF Core tickets. Based on my reading it looks like EF Core will eventually make some changes but not until EF 7. That being said I've also seen that there are ways to rewrite your query to get it to work. Not sure if that option is something you guys could implement inside the ToDataSourceResult method but it would be nice you could investigate that otherwise switching to your core library might be a no-go for a lot of people.
Hi Brandon,
Indeed this is my understanding as well, that EF Core is working on fixing the issues related to the use of the GropuBy operator. Probably there are also ways to rewrite the query in order for it to be translatable, but this is indeed a complex task by itself and we do have to keep in mind all possible scenarios involving grouping of data. We have been reviewing this case along with similar issues reporter and upon discussing this with the dev team we will consider investigating a possible implementation to handle it. That said I cannot confirm or deny whether one will be implemented or not, prior to the release of EF Core 7.0, which to my knowledge is currently scheduled for release in November 2022, along with .NET 7.
I can see that version 2022.3.1109 supports .NET 7. Has it been fixed the issue with grouping in ToDataSourceResult method?
Hi Agustin,
Indeed, as of the R3 2022 SP1 release, the Telerik UI for ASP.NET Core suite introduces .NET 7 Official Support.
Having this in mind, you can find a list of all the available fixes and features for a particular release within our "Release History" section:
That being said, again, if currently running the LINQ query with the EF Core 7.0 as an autonomous query does not produce errors, and the error occurs only when using the ToDataSourceResult method consider providing an isolated sample app where this for further examinations, as my colleague had mentioned previously, either by submitting a support ticket or directly within this thread.
Is this issue resolve? I just tested it on EF 7.0 but get the same error.
My testing is very simple.
In controller,
public ActionResult PositionNumber_List([DataSourceRequest] DataSourceRequest request)
{
var postionnumbers = from c in _context.ActivePositionExtracts
select c;
var dsResult = postionnumbers.ToDataSourceResult(request);
return Json(dsResult);
}
In the view,
@(
Html.Kendo().Grid<ActivePositionExtract>()
.Name("ActivePositionSelection")
.Columns(columns =>
{
columns.Bound(p => p.PositionNumber).Width(100).Filterable(false);
columns.Bound(p => p.EmployeeFirstName).Width(200);
columns.Bound(p => p.EmployeeLastName).Width(200);
columns.Bound(p => p.PositionFillStatus).Width(200);
columns.Bound(p => p.CrteDttm).Format("{0:dd/MM/yyyy}");
})
.Pageable(pageable => pageable.ButtonCount(5))
.Filterable()
.Groupable()
.Sortable()
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single))
.PersistSelection(true)
.Navigatable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(m => m.Id("PositionNumber"))
.PageSize(10)
.Read(read => read.Action("PositionNumber_List", "Grid"))
)
)
Same error
System.InvalidOperationExceptionHResult=0x80131509
Message=The LINQ expression 'DbSet<ActivePositionExtract>()
.Select(c => c)
.OrderBy(item => item.PositionFillStatus)
.Skip(__p_0)
.Take(__p_1)
.GroupBy(item => item.PositionFillStatus)
.OrderBy(group14577955 => group14577955.Key)
.Select(group14577955 => new AggregateFunctionsGroup{
Key = group14577955.Key,
ItemCount = group14577955
.AsQueryable()
.Count(),
HasSubgroups = False,
Member = "PositionFillStatus",
Items = group14577955
}
)' could not be translated. Additional information: Translation of 'Select' which contains grouping parameter without composition is not supported. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.Expand(Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.System.Collections.IEnumerable.GetEnumerator()
at Kendo.Mvc.Extensions.QueryableExtensions.Execute[TModel,TResult](IQueryable source, Func`2 selector)
at Kendo.Mvc.Extensions.QueryableExtensions.CreateDataSourceResult[TModel,TResult](IQueryable queryable, DataSourceRequest request, ModelStateDictionary modelState, Func`2 selector)
at Kendo.Mvc.Extensions.QueryableExtensions.ToDataSourceResult(IQueryable queryable, DataSourceRequest request, ModelStateDictionary modelState)
at Kendo.Mvc.Extensions.QueryableExtensions.ToDataSourceResult(IQueryable queryable, DataSourceRequest request)
at WebApp.Controllers.GridController.PositionNumber_List(DataSourceRequest request) in
Hi Jerome,
I noticed that you have opened a separate ticket thread in regard to the aforementioned inquiry. For the benefit of the community, I am also posting my colleague's answer here as well:
"The Queryable extension methods of the Kendo.Mvc library - ToDataSourceResult and ToDataSourceResultAsync and their overloads, rely and depend on the LINQ library. Depending on the whether grouping, aggregates etc. are enabled the generated queries can get extremely complex and thus at some point the LINQ library may fail to translate them. Inspecting the stack trace of the exception it still appears the issue is in LINQ not being able to translate the generated query."
"While indeed EF Core 7 supports GroupBy entity type, I see there are still many improvements on the GroupBy functionality left to implement. We have reviewed the current implementation of the way the grouping logic is executed and the query generated, though we do not see a way to generate a different query to handle this internally".
That said, the option we can currently suggest is to write a custom query that can be successfully translated and pass the resulting data to a DataSourceResult object, as colleague Aleksandar mentioned in his previous replies:
https://demos.telerik.com/aspnet-core/grid/customajaxbinding
Basically, I wrote my own CreateDataSourceResult method, and where in the code is:
if (!request.GroupPaging || !request.Groups.Any())
source1 = source1.Page(request.Page - 1, request.PageSize);
else if (request.GroupPaging && !request.Groups.Any())
source1 = source1.Skip(request.Skip).Take(request.Take);
I left it like this:
if (!request.GroupPaging || !request.Groups.Any())
source1 = source1.Page(request.Page - 1, request.PageSize).Cast<T>().ToList().AsQueryable();
else if (request.GroupPaging && !request.Groups.Any())
source1 = source1.Skip(request.Skip).Take(request.Take);
It could be a way...I managed to work around the problem here.
Basically, I wrote my own CreateDataSourceResult method, and where in the code is:
if (!request.GroupPaging || !request.Groups.Any())
source1 = source1.Page(request.Page - 1, request.PageSize);
else if (request.GroupPaging && !request.Groups.Any())
source1 = source1.Skip(request.Skip).Take(request.Take);
I left it like this:
if (!request.GroupPaging || !request.Groups.Any())
source1 = source1.Page(request.Page - 1, request.PageSize).Cast<T>().ToList().AsQueryable();
else if (request.GroupPaging && !request.Groups.Any())
source1 = source1.Skip(request.Skip).Take(request.Take);
It could be a way...
Hi Adriano,
Thank you for sharing the approach with the community.
Kind Regards,
Anton Mironov

Hello, I have the same problem but this topic is 2 years old.
We're now on .net 8 and just a simple grouping is still not working?
@Telerik When this will be fixed because it's not a EF core issue, it's clearly down to Telerik component.
Hi Flavien,
Since this topic seems to be a duplicate from a previous communication of ours, I'm also sending my findings within the public forum as well. So that members of the community can benefit from it as well:
"Generally, the Queryable extension methods of the Kendo.Mvc library - ToDataSourceResult and ToDataSourceResultAsync and their overloads, rely and depend on the LINQ library. Depending on the whether grouping, aggregates etc. are enabled the generated queries can get extremely complex and thus at some point the LINQ library may fail to translate them. Let me know if this is the case at your end."
This can be verified by exploring the Stack Trace of the error, as it spirals upward to the usage of the EntityFrameworkCore library. Thus, I am inclined to thinking that the issue may be revolved around either the ORM, or the LINQ library itself.
I have further dug into this and it appears that although the newest .NET Core version implies that the issue is resolved. There are still clients that exhibit the same behavior. As described in the following public issue:
In order to not reach to any final conclusions, I have also embarked on the task of accessing whether the composition of the queries on our side, could be causing the issue as well. An whether it could be stumbling upon this bug.
That said, the option I can currently suggest is to write a custom query that can be successfully translated and pass the resulting data to a DataSourceResult object, as demonstrated in the Custom Ajax Binding for the Grid Demo:
The aforementioned demo showcases, how you can manually compose the Grouping Expressions yourself:
public static IEnumerable ApplyOrdersGrouping(this IQueryable<OrderViewModel> data, IList<GroupDescriptor>
groupDescriptors)
{
if (groupDescriptors != null && groupDescriptors.Any())
{
Func<IEnumerable<OrderViewModel>, IEnumerable<AggregateFunctionsGroup>> selector = null;
foreach (var group in groupDescriptors.Reverse())
{
if (selector == null)
{
if (group.Member == "ShipCity")
{
selector = Orders => BuildInnerGroup(Orders, o => o.ShipCity);
}
else if (group.Member == "ShipAddress")
{
selector = Orders => BuildInnerGroup(Orders, o => o.ShipAddress);
}
else if (group.Member == "ShipName")
{
selector = Orders => BuildInnerGroup(Orders, o => o.ShipName);
}
else if (group.Member == "ShipCountry")
{
selector = Orders => BuildInnerGroup(Orders, o => o.ShipCountry);
}
}
else
{
if (group.Member == "ShipCity")
{
selector = BuildGroup(o => o.ShipCity, selector);
}
else if (group.Member == "ShipAddress")
{
selector = BuildGroup(o => o.ShipAddress, selector);
}
else if (group.Member == "ShipName")
{
selector = BuildGroup(o => o.ShipName, selector);
}
else if (group.Member == "ShipCountry")
{
selector = BuildGroup(o => o.ShipCountry, selector);
}
}
}
return selector.Invoke(data).ToList();
}
return data.ToList();
}
private static Func<IEnumerable<OrderViewModel>, IEnumerable<AggregateFunctionsGroup>>
BuildGroup<T>(Expression<Func<OrderViewModel, T>> groupSelector, Func<IEnumerable<OrderViewModel>,
IEnumerable<AggregateFunctionsGroup>> selectorBuilder)
{
var tempSelector = selectorBuilder;
return g => g.GroupBy(groupSelector.Compile())
.Select(c => new AggregateFunctionsGroup
{
Key = c.Key,
HasSubgroups = true,
Member = groupSelector.MemberWithoutInstance(),
Items = tempSelector.Invoke(c).ToList()
});
}
private static IEnumerable<AggregateFunctionsGroup> BuildInnerGroup<T>(IEnumerable<OrderViewModel>
group, Expression<Func<OrderViewModel, T>> groupSelector)
{
return group.GroupBy(groupSelector.Compile())
.Select(i => new AggregateFunctionsGroup
{
Key = i.Key,
Member = groupSelector.MemberWithoutInstance(),
Items = i.ToList()
});
}
I think I found a possible solution.
The problem occurs using the query below, assembled by Telerik routine:
var temp = _db.Pessoa
.OrderBy(item => item.Email)
.Skip(0)
.Take(40)
.GroupBy(item => item.Email)
.OrderBy(g => g.Key)
.Select(g => new AggregateFunctionsGroup
{
Key = g.Key,
ItemCount = g.Count(),
HasSubgroups = false,
Member = "Email",
AggregateFunctionsProjection = new
{
Count_Referencia = _db.Pessoa
.Select(t => new
{
t.IdPessoa,
t.Referencia,
t.Nome_RazaoSocial,
t.Apelido_Fantasia,
t.CPF_CNPJ,
t.RG_IE,
t.Email
})
.OrderBy(item => item.Email)
.Where(item => item.Email == g.Key)
.Count()
},
Items = g
})
.ToList();
But I noticed that if we take the line where Items = g is and leave it like this:
var temp = _db.Pessoa
.OrderBy(item => item.Email)
.Skip(0)
.Take(40)
.GroupBy(item => item.Email)
.OrderBy(g => g.Key)
.Select(g => new AggregateFunctionsGroup
{
Key = g.Key,
ItemCount = g.Count(),
HasSubgroups = false,
Member = "Email",
AggregateFunctionsProjection = new
{
Count_Referencia = _db.Pessoa
.Select(t => new
{
t.IdPessoa,
t.Referencia,
t.Nome_RazaoSocial,
t.Apelido_Fantasia,
t.CPF_CNPJ,
t.RG_IE,
t.Email
})
.OrderBy(item => item.Email)
.Where(item => item.Email == g.Key)
.Count()
},
Items = g.Select(t => new
{
t.IdPessoa,
t.Referencia,
t.Nome_RazaoSocial,
t.Apelido_Fantasia,
t.CPF_CNPJ,
t.RG_IE,
t.Email
})
})
.ToList();
The problem stops happening.
In other words, Telerik just rewrites, in ToDataSourceResultAsync, the routine that assembles the query with AggregateFunctionsGroup, so that in the Items property, the group is added with the same select that was used in the main query.
Items = g
It looks like this:
Items = g.Select(t => t)
It also works, you just need to have Select after the group parameter
Hi Adriano,
I will make sure to pass these details to our developer subject matter experts. So that they can further examine the validity of this alteration. And whether or not it might impact other logical query segments.
Thank you for sharing your findings, this is of huge help!
Let me know if the solution is implemented, as we are waiting for this issue to be resolved before we can purchase the tool
Hi Adriano,
Our development team investigated the case in-depth, and here is their feedback regarding the matter:
The issue originates from EF Core and it occurs when the query cannot be translated to SQL. Before EF Core 6, when the query was not translatable to SQL, the data was fetched in memory to execute the query instead of converting it to SQL and executing it in the database server. This behavior has changed since EF Core 6 and resulted in the current issue.
Having this in mind, we recommend calling ToList() before passing the data to the ToDataSourceResult() method. This way, the query will be executed successfully and the issue will be resolved.
If any questions arise, don't hesitate to share them.
Best,
Mihaela
If I understand this correctly, you're suggesting I call .ToList() on a table of >500K rows - to enable grouping? I'm using .NET 8.
If that's the case, it's not a workable solution. WAY too much overhead.
Hi Mike,
In this case, when dealing with a large amount of data, me and my colleagues recommend writing a custom query that can be translated successfully to SQL and then passing the result to the "Data" property of the DataSourceResult object:
var result = new DataSourceResult()
{
Data = grouopedDataCollection,
Total = total
};
return Json(result);
Best,
Mihaela
Mihaela,
My case is exactly the same as Mike's, it's a table with thousands of records.The main advantage of using your Grid component is exactly the fact that it converts the query directly to SQL, it has been like this for over 10 years.
Anyway, I know about EF Core's limitation regarding this and I am in direct contact with their development team about a solution.
But given the above, I believe that your tool is not behaving as expected.
Calling a ToList is not the solution.
I found the problem, and described above how to make a quick fix.
Is it possible for your team to do this simple solution when formulating the query? Or will we have to look for another tool?
ToList() is definitely not a solution!!!
Is it so difficult, in the query constructor, to place the same query as the main query, or just add a .Select() at the end of the query?
Hi Adriano,
As I mentioned in the above comments, the issue originates from EF Core and as such is outside of our scope.
Regarding your comment "But given the above, I believe that your tool is not behaving as expected." - would you elaborate further? Also, feel free to share your feedback and ideas on how the ToDataSourceResult() method can be enhanced by submitting a feature request in our Feedback Portal? We regularly monitor the items there, and the ones that gain popularity are usually included in the roadmap.
Best,
Mihaela
Hi Mihaela,
I already gave the solution above. As mentioned: In the routine where the AggregateFunctionsGroup is created, the Items property must not only be the query itself, but also the fields specified in the main Select. Or, the call to the Select() method must simply be added.
.Select(g => new AggregateFunctionsGroup
{
Key = g.Key,
ItemCount = g.Count(),
HasSubgroups = false,
Member = "Member_Group_Field",
AggregateFunctionsProjection = new
{
Count_Referencia = _db.Table
.Select(t => new
{
Fields....
})
.OrderBy(item => item.Member_Group_Field)
.Where(item => item.Member_Group_Field== g.Key)
.Count()
},
Items = g.Select(t => new
{
Fields
})
})
Hi Adriano,
I have logged it as a feature request on your behalf in our Public Feedback Portal. You can follow the progress here and receive status updates:
Our engineering team will evaluate your suggestion and share their feedback.
As a token of appreciation for your feedback and solution, I have updated your Telerik account points.
Best,
Mihaela