efcore: This overload is currently not supported.
I try to create an extension expression that has no impact on the generated SQL result.
I only want to react in my custom QueryCompiler method public override TResult Execute<TResult>(Expression query).
But compiling the query failed. How do I “register” my extension or how to tell to ignore it at the compilation or do I have to rewrite the query befor compilation and remove my custom part?
Exception message:
Could not parse expression 'value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Model.AzureSQL.Core.Entities.Inverter]).*****.Where(d => (d.ID == __expectedResult_ID_0)).Cacheable(00:00:05)': This overload of the method 'EntityFrameworkQueryableExtensions.Cacheable' is currently not supported.
Steps to reproduce
I created a custom Expression close to the AsNotTracking expression.
public class CacheableExpressionNode : ResultOperatorExpressionNodeBase
{
[...]
public class CacheableResultOperator : SequenceTypePreservingResultOperatorBase, IQueryAnnotation
{
[...]
public static class EntityFrameworkQueryableExtensions
{
internal static readonly MethodInfo CacheablehMethodInfo
= typeof(EntityFrameworkQueryableExtensions)
.GetTypeInfo().GetDeclaredMethod(nameof(Cacheable));
public static IQueryable<T> Cacheable<T>(this IQueryable<T> source, [NotParameterized] TimeSpan timeToLive)
{
Check.NotNull(source, nameof(source));
Check.NotNull(timeToLive, nameof(timeToLive));
return
source.Provider is EntityQueryProvider
? source.Provider.CreateQuery<T>(
Expression.Call(
instance: null,
method: CacheablehMethodInfo.MakeGenericMethod(typeof(T)),
arg0: source.Expression,
arg1: Expression.Constant(timeToLive)))
: source;
}
}
Further technical details
Further technical details EF Core version: 2.2.0 Database Provider: any
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 27 (11 by maintainers)
@SteffenMangold - I think I understood now what is happening. The issue is EF Core returns result type or IEnumerable. The result type would always execute query and gives back the single result. (the First call) but the
IEnumerablewill execute query only when it is enumerated. In other word, in order to store results ofIEnumerablein cache, you would actually need to enumerate it. So calling ToList method on it would be one way to do it.Just build extension methods on Queryable. And they will be in expression tree as MethodCallExpression. At that point they are same as having
Queryable.Where, so there shouldn’t be any need to inherit from anything (unless I am misunderstanding something).I plan to update the extension list soon!
Good work, Steffen!
Just finished it before a few seconds! It works fantastic now. Thank you very much for your help so long.
Override the service and add additional line like this https://github.com/aspnet/EntityFrameworkCore/blob/359424adda850025d55e912684df4fa065e23948/src/EFCore/Query/Internal/MethodInfoBasedNodeTypeRegistryFactory.cs#L40-L41
If you decide to add custom node in expression tree which you want to be available at compile time then