Query Execution (Client/Server) - determination logic and perhaps notification/logging of the same - Hacks?
See original GitHub issueI was wondering if there is a way to figure out whether my Linq queries were evaluated at the client or the server side, may be via some flag, logs etc. in EF6 world?
Objective: We are in the process of migrating from EF6 to EFCore 6 and since client side evaluation is disabled in EFCore_v6, hence we need to know what all queries will fail to be exported from EF6.
I came across the below codes in EF6 which seems to have some determining logic as to whether the expression is evaluable at the Client or the Server side but I am not sure if that’s the only place:
At Funcletizer.cs
// <summary>
// Walks the expression tree and replaces client-evaluatable expressions with constants
// or QueryParameterExpressions.
// </summary>
private sealed class FuncletizingVisitor : EntityExpressionVisitor
{
private readonly Funcletizer _funcletizer;
private readonly Func<Expression, bool> _isClientConstant;
private readonly Func<Expression, bool> _isClientVariable;
private readonly List<Func<bool>> _recompileRequiredDelegates = new List<Func<bool>>();
........
And also the below at Translator.cs:
// <summary>
// This method is used to determine whether client side evaluation should be done,
// if the property can be evaluated in the store, it is not being evaluated on the client
// </summary>
internal static bool CanFuncletizePropertyInfo(PropertyInfo propertyInfo)
{
PropertyTranslator propertyTranslator;
// In most cases, we only allow funcletization of properties that could not otherwise be
// handled by the query pipeline. ICollection<>.Count is the one exception to the rule
// (avoiding a breaking change)
return GenericICollectionTranslator.TryGetPropertyTranslator(propertyInfo, out propertyTranslator) ||
!TryGetTranslator(propertyInfo, out propertyTranslator);
}
Could you please guide me to something where I can get some indication of whether the LINQ query that I am executing is either getting client evaluated or server evaluated or both (as in some part at client and other at the server end)?
Further technical details
EF version: EF 6.4.0 Database Provider: EntityFramework.SqlServer Operating system: Windows 10 IDE: Visual Studio 2017
Issue Analytics
- State:
- Created 2 years ago
- Reactions:4
- Comments:9 (3 by maintainers)
Can you please refer to this specific ask recurring in user issues? Most our users who are using EF6 wants to migrate to EF Core and they want the queries which are running in EF6 runs in EF Core without throwing exception. In most cases, users are not even expecting to run the same SQL as long as it generates correct result. Given that EF6 also didn’t allow client eval other than top level projection and EF Core follows same principle, there is not much gap in terms of client evaluation. There are few operators combination like GroupBy/GroupJoin which does require additional client evaluation which is not really translatable to database SQL directly and which EF6 performed and EFCore lacking. We have plan to address some of these in https://github.com/dotnet/efcore/issues/24106
Irrespective of migration from EF6 to EF Core, a tool to identify the server/client eval part separately in a query may be interesting but not much useful to end customers as long as what EF does under the hood is correct performant results.
I don’t think anything has changed fundamentally in this issue from what I have responded last time here.
As for specific ask for a tool to tell if query will evaluate on client or server without actually writing such query, we cannot provide such tool. Not only there is not frequent ask for it (most customers wants that their query runs when migrating rather than caring about where does it evaluate what), from the infinite problem space of LINQ query world, I believe it is impossible to arrive at a tool which can accurately identify such behavior. Unless there is compelling reason to implement such tool and actually a logical solution which shows that such a tool can work correctly in most case (even if not accurately in 100% cases), we can look into it.