System.Linq.Dynamic.Core icon indicating copy to clipboard operation
System.Linq.Dynamic.Core copied to clipboard

Exception after upgrade to .net core 3

Open MoRooz opened this issue 6 years ago • 7 comments

this is source of exception

q2.Select("new(Key.CallItemStatus as CallItemStatus, it.Count() as Count))")

the same code works fine in .net core 2.2

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'index')
   at System.Linq.Expressions.InstanceMethodCallExpression1.GetArgument(Int32 index)
   at System.Dynamic.Utils.ListArgumentProvider.GetElement(Int32 index)
   at System.Dynamic.Utils.ListProvider`1.get_Item(Int32 index)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityEqualityRewritingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityEqualityRewritingExpressionVisitor.<VisitMemberInit>g__VisitMemberBindings|9_0(ReadOnlyCollection`1 bindings)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityEqualityRewritingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
   at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityEqualityRewritingExpressionVisitor.VisitUnary(UnaryExpression unaryExpression)
   at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityEqualityRewritingExpressionVisitor.VisitSelectMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityEqualityRewritingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityEqualityRewritingExpressionVisitor.Rewrite(Expression expression)
   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.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   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.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at System.Linq.Dynamic.Core.DynamicEnumerableExtensions.CastToList[T](IEnumerable source)
   at System.Linq.Dynamic.Core.DynamicEnumerableAsyncExtensions.<>c__DisplayClass7_0`1.<CastToListAsync>b__0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---

MoRooz avatar Oct 26 '19 10:10 MoRooz

@MoRooz If possible, provide a full working sample project.

StefH avatar Oct 26 '19 11:10 StefH

When calling ToArray() on the q1 like:

var q1 = context.Blogs.GroupBy(context.Blogs.KeySelectorExpression(groupByList));
var q1a = q1.ToArray();

Already gives an exception:

System.InvalidOperationException: 'Client projection contains reference to constant expression of type: Microsoft.EntityFrameworkCore.Metadata.IPropertyBase. This could potentially cause memory leak.'

StefH avatar Oct 27 '19 07:10 StefH

See also

  • https://github.com/aspnet/EntityFrameworkCore/issues/17623
  • https://github.com/aspnet/EntityFrameworkCore/pull/18051
  • https://go.microsoft.com/fwlink/?linkid=2103067

When upgrading to 3.1 preview, I get this better error:

System.InvalidOperationException: 'Client projection contains reference to constant expression of 'Microsoft.EntityFrameworkCore.Metadata.IPropertyBase' which is being passed as argument to method 'TryReadValue'. This could potentially cause memory leak. Consider assigning this constant to local variable and using the variable in the query instead. See https://go.microsoft.com/fwlink/?linkid=2103067 for more information.'

StefH avatar Oct 27 '19 08:10 StefH

memory leak is probably because of InMemory Provider, here is Sqlite one, with another error

Client side GroupBy is not supported

var options = new DbContextOptionsBuilder<BloggingContext>().UseSqlite("Filename=MyDatabase.db").Options;

            using (var context = new BloggingContext(options))
            {
                context.Database.EnsureCreated();

                context.Blogs.Add(new Blog { CategoryId = 1, PageId = 2 });
                context.Blogs.Add(new Blog { CategoryId = 1, PageId = 3 });
                context.Blogs.Add(new Blog { CategoryId = 2, PageId = 2 });
                context.Blogs.Add(new Blog { CategoryId = 2, PageId = 2 });
                context.SaveChanges();


                // not working
                var groupByList = new List<string> { "CategoryId" };
                var q1 = context.Blogs.GroupBy(context.Blogs.KeySelectorExpression(groupByList));
                //var q11List = q1.ToArray();

                var q3 = System.Linq.Dynamic.Core.DynamicQueryableExtensions.GroupBy(context.Blogs, "CategoryId");
                var q31List = q3.ToDynamicArray();


                var q2 = q1.Select("new (Key.CategoryId as CategoryId, it.Count() as Count)");
                //var q2 = q1.Select("new (it.Key.CategoryId as CategoryId, it.Count() as Count)");
                var result0 = q2.ToDynamicList<object>();


                // working
                var g0 = context.Blogs.GroupBy("new (CategoryId)");
                var g1 = g0.Select("new (it.Key.CategoryId as CategoryId, it.Count() as Count)");
                var list = g1.ToDynamicList<object>();
            }

both LinqGroupBy and DynamicLinq GroupBy has this error

MoRooz avatar Oct 27 '19 08:10 MoRooz

seems some sql aggregate is necessary in select

https://github.com/aspnet/EntityFrameworkCore/issues/18102#issuecomment-536231179

this is working,


var groupByList = new List<string> { "CategoryId","PageId" };
var q2 = context.Blogs.GroupBy(context.Blogs.KeySelectorExpression(groupByList)).Select("new (it.Key as Key, it.Count() as Count)");
var q2List = q2.ToDynamicList<object>();

now only if its possible to get flatten key.

current

{{ Key = { CategoryId = 1, PageId = 2 }, Count = 34 }}

need (used to work in net 2.2 with Key.Property in select)

{{ CategoryId = 1, PageId = 2, Count = 34 }}

MoRooz avatar Oct 27 '19 09:10 MoRooz

@MoRooz Thanks for researching. Would it be an idea to add this in a readable markdown format in a wiki? If so, can you please help.

StefH avatar Oct 28 '19 07:10 StefH