dotnet / dotnet/efcore

Error applying projection

Open
#30,012 8 comments 1 reaction 0 assignees View on GitHub
area-groupby area-query customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

Hello,
summarizing, from a third part software I receive an expression that contain a `IQueryable`, I also receive the `TEntity `EF Model metadata. This expression may contains any valid query.
Under some circumstances, I have to limit the materialized data, so I check the Model metadata, I choice wich properties I want to retrive from database and I add a projection to the query attaching a select call to the expression.

All seems work but in some cases the query fails despite it is a valid query.

for example, having this model

```
public class Nation
{
public Guid NationID { get; set; }
public string NationName { get; set; }
public virtual ICollection Cities { get; set; }
}
public class City
{
public Guid CityID { get; set; }
public virtual Nation Nation { get; set; }
public string CityName { get; set; }

public virtual ICollection Districts { get; set; }
}

public class District
{
public Guid DistrictID { get; set; }
public string DistrictName { get; set; }
public virtual City City { get; set; }
}

```

when I receive this query
`ctx.Set().Select(itm => itm.Cities.First().Districts)`

I apply the projection and I get the query
`ctx.Set().Select(itm => itm.Cities.First().Districts).Select(itm => itm.Select(itmSelect => new { DistrictName = itmSelect.DistrictName })).ToArray();
`
this fails with

```
System.ArgumentException
HResult=0x80070057
Messaggio=Property 'System.String DistrictName' is not defined for type 'System.Collections.Generic.ICollection`1[ConsoleApp1.District]' Arg_ParamName_Name
Origine=System.Linq.Expressions
Analisi dello stack:
in System.Linq.Expressions.Expression.Property(Expression expression, PropertyInfo property)
in System.Linq.Expressions.Expression.MakeMemberAccess(Expression expression, MemberInfo member)
in System.Linq.Expressions.MemberExpression.Update(Expression expression)
in Microsoft.EntityFrameworkCore.Query.ReplacingExpressionVisitor.VisitMember(MemberExpression memberExpression)
in System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
in System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
in System.Linq.Expressions.ExpressionVisitor.VisitNew(NewExpression node)
in System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor)
in Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ProcessSelect(NavigationExpansionExpression source, LambdaExpression selector)
in Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
in System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
in Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.PendingSelectorExpandingExpressionVisitor.Visit(Expression expression)
in Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.Expand(Expression query)
in Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query)
in Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
in Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.b__0()
in Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
in Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
in Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
in System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
in System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
in System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
in ConsoleApp1.Program.Main(String[] args) in C:\EFError\ConsoleApp1\ConsoleApp1\Program.cs: riga 16

```

Of course the query fails also if I directly write it in a test project(like the attached)

another expample is this query :
`ctx.Set().GroupBy(itm => EF.Property(itm, "NationID")).Select(itm => itm.First())
`
after the projection is added
`ctx.Set().GroupBy(itm => EF.Property(itm, "NationID")).Select(itm => itm.First()).Select(itmSelect=>new {itmSelect.CityName}).ToArray();
`
this fail with :
```
System.InvalidOperationException
HResult=0x80131509
Messaggio=The LINQ expression 'ProjectionBindingExpression: 0' could not be translated. 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.
Origine=Microsoft.EntityFrameworkCore.Relational
Analisi dello stack:
in Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
in Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMember(MemberExpression memberExpression)
in System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
in Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
in Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitNew(NewExpression newExpression)
in System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor)
in Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
in Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)
in Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
in Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
in System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
in Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
in Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.b__0()
in Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
in Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
in Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
in System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
in System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
in System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
in ConsoleApp1.Program.Main(String[] args) in C:\EFError\ConsoleApp1\ConsoleApp1\Program.cs: riga 18

```

Can you please check where the problem is and advise a workaround?

Many thanks

[ConsoleApp1.zip](https://github.com/dotnet/efcore/files/10380986/ConsoleApp1.zip)

Provider : Microsoft.EntityFrameworkCore.SqlServer 6.0.12

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.