Error applying projection
- 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
Assessment
This issue has not been assessed yet.