Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.OrderBy on column 2 or more navigation properties away + .Include throws exception #3811

Closed
jparish9 opened this issue Nov 19, 2015 · 32 comments
Assignees
Labels

Comments

@jparish9
Copy link

Windows 10, VS 2015, IIS Express, SQL Server Express 2014, EF 7.0.0-rc1-final, ASP.NET 6.0.0-rc1-final

After upgrading to RC1, I am seeing an exception Unable to cast object of type 'System.Linq.Expressions.FieldExpression' to type 'System.Linq.Expressions.ParameterExpression'. when querying using .OrderBy on a navigation property table 2 or more tables away from the base table, plus .Include. This was working in beta8. I reduced the test case as much as possible to illustrate:

Models:

    public class Blog
    {
        public int BlogId { get; set; }

        public string Title { get; set; }
    }
    public class Post
    {
        public int PostId { get; set; }

        public int BlogId { get; set; }

        public Blog Blog { get; set; }

        public string PostText { get; set; }
    }
    public class Comment
    {
        public int CommentId { get; set; }

        public int PostId { get; set; }

        public Post Post { get; set; }

        public int CommentText { get; set; }
    }

The query that causes an exception is:

   _dbContext.Comments
                    .Include(c => c.Post)
                    .OrderBy(c => c.Post.Blog.BlogId)
                    .ToList();

Stack trace:

Unable to cast object of type 'System.Linq.Expressions.FieldExpression' to type 'System.Linq.Expressions.ParameterExpression'.
   at Microsoft.Data.Entity.Query.ExpressionVisitors.Internal.IncludeExpressionVisitor.VisitMethodCall(MethodCallExpression expression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.Data.Entity.Query.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.Data.Entity.Query.ExpressionVisitors.Internal.IncludeExpressionVisitor.VisitMethodCall(MethodCallExpression expression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.Data.Entity.Query.ExpressionVisitors.ExpressionVisitorBase.Visit(Expression expression)
   at Microsoft.Data.Entity.Query.RelationalQueryModelVisitor.IncludeNavigations(IncludeSpecification includeSpecification, Type resultType, LambdaExpression accessorLambda, Boolean querySourceRequiresTracking)
   at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.IncludeNavigations(QueryModel queryModel, IReadOnlyCollection`1 includeSpecifications)
   at Microsoft.Data.Entity.Query.RelationalQueryModelVisitor.IncludeNavigations(QueryModel queryModel, IReadOnlyCollection`1 includeSpecifications)
   at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.IncludeNavigations(QueryModel queryModel)
   at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
   at Microsoft.Data.Entity.Storage.Database.CompileQuery[TResult](QueryModel queryModel)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Data.Entity.Query.Internal.QueryCompiler.<>c__DisplayClass18_0`1.<CompileQuery>b__0()
   at Microsoft.Data.Entity.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.Data.Entity.Query.Internal.QueryCompiler.CompileQuery[TResult](Expression query)
   at Microsoft.Data.Entity.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.Data.Entity.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at Remotion.Linq.QueryableBase`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
...

Both the .Include and the .OrderBy are necessary to see this exception, and the .OrderBy must be ordering by a column at least 2 navigation properties away from the base table. For example,

    _dbContext.Comments
                    .Include(c => c.Post)
                    .OrderBy(c => c.Post.BlogId)
                    .ToList();

and

   _dbContext.Comments
                    .OrderBy(c => c.Post.Blog.BlogId)
                    .ToList();

both work fine.

@maumar maumar self-assigned this Nov 20, 2015
@maumar
Copy link
Contributor

maumar commented Nov 20, 2015

still repros in the current bits

maumar added a commit that referenced this issue Nov 20, 2015
…y + .Include throws exception

Problem was that in IncludeExpressionVisitor -> VisitMethodCall, when building entity accessor from a MemberExpression, we incorrectly assumed that member expression will always be one level.

Fix is to add a method that will go down the Expression chain to find a ParameterExpression which is the root of the given MemberExpression
@adrien-constant
Copy link

I have the same exception with a simple Where() clause.
It also happens only if there are Includes, and on columns at least 2 navigation properties away from the base table.

The stack strace is a bit different though :

mscorlib.dll!System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() Unknown
EntityFramework.Core.dll!Microsoft.Data.Entity.Query.Internal.QueryCompiler.CompileQuery.AnonymousMethod__0()   Unknown
EntityFramework.Core.dll!Microsoft.Data.Entity.Query.Internal.CompiledQueryCache.GetOrAddQuery<System.Collections.Generic.IEnumerable<Infrastructure.NotePrevention>>(object cacheKey, System.Func<System.Func<Microsoft.Data.Entity.Query.QueryContext, System.Collections.Generic.IEnumerable<Infrastructure.NotePrevention>>> compiler)  Unknown
EntityFramework.Core.dll!Microsoft.Data.Entity.Query.Internal.QueryCompiler.CompileQuery<System.Collections.Generic.IEnumerable<Infrastructure.NotePrevention>>(System.Linq.Expressions.Expression query)   Unknown
EntityFramework.Core.dll!Microsoft.Data.Entity.Query.Internal.QueryCompiler.Execute<System.Collections.Generic.IEnumerable<Infrastructure.NotePrevention>>(System.Linq.Expressions.Expression query)    Unknown
EntityFramework.Core.dll!Microsoft.Data.Entity.Query.Internal.EntityQueryProvider.Execute<System.Collections.Generic.IEnumerable<Infrastructure.NotePrevention>>(System.Linq.Expressions.Expression expression) Unknown
Remotion.Linq.dll!Remotion.Linq.QueryableBase<Infrastructure.NotePrevention>.GetEnumerator()    Unknown
System.Core.dll!System.Linq.Buffer<Infrastructure.NotePrevention>.Buffer(System.Collections.Generic.IEnumerable<Infrastructure.NotePrevention> source)  Unknown
System.Core.dll!System.Linq.Enumerable.ToArray<Infrastructure.NotePrevention>(System.Collections.Generic.IEnumerable<Infrastructure.NotePrevention> source) Unknown

EF 7 version RC1, SQL Server v12, I think it was working with beta8.

@rowanmiller rowanmiller added this to the 7.0.0 milestone Nov 20, 2015
maumar added a commit that referenced this issue Nov 23, 2015
…y + .Include throws exception

Problem was that in IncludeExpressionVisitor -> VisitMethodCall, when building entity accessor from a MemberExpression, we incorrectly assumed that member expression will always be one level.

Fix is to add a method that will go down the Expression chain to find root of the given MemberExpression.
CR: Andrew
maumar added a commit that referenced this issue Nov 23, 2015
…y + .Include throws exception

Problem was that in IncludeExpressionVisitor -> VisitMethodCall, when building entity accessor from a MemberExpression, we incorrectly assumed that member expression will always be one level.

Fix is to add a method that will go down the Expression chain to find root of the given MemberExpression.
CR: Andrew
@yuezhongxin
Copy link

I have also same exception, and this is my code:

public IQueryable<AdImageCreative> GetAdImageCreatives()
{
    var endDate = DateTime.Now.AddDays(-1);
    return _adImageCreatives
        .Include(x => x.AdImage)
        .Include(x => x.AdImageUnit)
        .Where(x => x.AdImage.IsActive && x.AdImageUnit.IsActive &&
        x.EndDate > endDate && x.IsActive)
        .OrderByDescending(x => x.DateUpdated);
}

[Fact]
public async Task GetAdImageCreativesTest()
{
    var AdImageCreatives = await _adImageCreativeRepository.GetAdImageCreatives().ToListAsync();
    Assert.NotNull(AdImageCreatives);
    AdImageCreatives.ForEach(x => Console.WriteLine($"{x.AdImageUnit.Name} - {x.AdImage.Title} - {x.AdImage.Url}- {x.AdImage.Link}"));
}

Error Message:

qq20151124-0 2x

If I remove .Include(x => x.AdImage) or .Include(x => x.AdImageUnit), it works

Windows 10, VS 2015, SQL Server 2014, EF 7.0.0-rc1-final

maumar added a commit that referenced this issue Nov 24, 2015
…y + .Include throws exception

Problem was that in IncludeExpressionVisitor -> VisitMethodCall, when building entity accessor from a MemberExpression, we incorrectly assumed that member expression will always be one level.

Fix is to add a method that will go down the Expression chain to find root of the given MemberExpression.
CR: Andrew
@maumar
Copy link
Contributor

maumar commented Nov 24, 2015

Fixed in 8c1e269

@maumar maumar closed this as completed Nov 24, 2015
@yuezhongxin
Copy link

@maumar Thank you, I should now what version of EF? To avoid this problem.

@maumar
Copy link
Contributor

maumar commented Nov 25, 2015

@yuezhongxin it just got checked in, and will be publicly available once passes our integration tests. This should be on the nightly feed tomorrow or within a few days at most. The build number will be 16425

@yuezhongxin
Copy link

@maumar Ok, thanks!

@yuezhongxin
Copy link

@maumar Now I use this version 7.0.0-rc2-16432, and this problem does not occur.

Please help me look at this issue #3887, thanks!

@rexebin
Copy link

rexebin commented Feb 8, 2016

How do I get the latest version like EF 7 RC2 please? Do I need to fetch the repo, build and replace the ef7 packages in my project?

@adrien-constant
Copy link

@rexebin you can use this nuget.config content :

<add key="ASP.NET Nightly" value="https://www.myget.org/F/aspnetcidev/api/v3/index.json" protocolVersion="3" />
<add key="ASP.NET vNext" value="https://www.myget.org/F/aspnetvnext/api/v3/index.json" protocolVersion="3" />
<add key="dotnet-core" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" protocolVersion="3"  />
<add key="dotnet-cli" value="https://www.myget.org/F/dotnet-cli/api/v3/index.json" protocolVersion="3"  />

@rexebin
Copy link

rexebin commented Feb 8, 2016

@adrien-constant Thank you very much, now updating my packages to the latest rc2.

@rexebin
Copy link

rexebin commented Feb 8, 2016

@adrien-constant After installing RC2, the project builds ok, but it would not start, not with vs 2015, not with dnx. may due to version compatibility. Is there a guidance somewhere where I could follow and start using EF7 RC2 please? I encountered a few problems with RC1, which are fixed in RC2.

Thank you.

@rowanmiller
Copy link
Contributor

@rexebin our guidance would be to not use our nightly builds at the moment. Things are very unstable as we move over to .NET CLI from DNX. Because of changes in package structure etc. it is hard to get a stable setup where things install, compile, and run. Things will settle down over the coming weeks.

@rexebin
Copy link

rexebin commented Feb 8, 2016

@rowanmiller Thank you very much. I will wait for an official release then.

@adrien-constant
Copy link

@rexebin I'm using the latest unstable version of dnx and it works well. In my case, I need the latest bug fixes.

Nightly and unstable are not for everyone, but in case you want it, here are the commands you need to run to update to the a version of dnx that should work the the nightly builds :

set DNX_UNSTABLE_FEED=https://www.myget.org/F/aspnetcidev/api/v2/
dnvm upgrade -u 1.0.0-rc2-16453
dnvm upgrade -r coreclr -u 1.0.0-rc2-16453
dnvm use 1.0.0-rc2-16453 -p

@rexebin
Copy link

rexebin commented Feb 9, 2016

@adrien-constant I did upgrade the dnx to rc2 and made sure that I used it in my project with global.json and set the rc2 to default. The project does not start. Do I need to upgrade other components to rc2 or can I just upgrade ef7 to rc2? Is the new dnx compatible with rc1-final packages like MVC?

@Nikhil1292
Copy link

Still reproduce this problem
_dbContext.Comments
.Include(c => c.Post)
.Where(c => c.Post.Blog.BlogId)
.ToList();

@RiyasMeeran
Copy link

.Include(m => m.Product.Company).AsEnumerable().Where(m => m.Project.Company.Id==1)

@Carpi68
Copy link

Carpi68 commented Apr 11, 2016

@rowanmiller: Is it already recommended to use the latest nightly build to resolve this issue?
My workaround is to use IEnumerable<T> instead of IQueryable<T> to query my DbContext, because the exception seems only to be thrown in the latter case.
But this is badly slowing down my performance (I'm working with large tables) because IEnumerable<T> will run the query in memory instead of running on the database server.
I guess there are also many other improvements available since November.
My application is a WPF application (VS2013). How can I upgrade from rc1 to a nightly build? Do I have to use nuget?

@ErikEJ
Copy link
Contributor

ErikEJ commented Apr 11, 2016

@Carpi68 You must use VS 2015 with the latest NuGet updates (3.4.2) in order to use RC2+

@Carpi68
Copy link

Carpi68 commented Apr 11, 2016

@ErikEJ Thanks for this hint! I just updated to VS 2015 and the latest NuGet.
What do I need to do next to get access to any RC2+ build?

@ErikEJ
Copy link
Contributor

ErikEJ commented Apr 11, 2016

@Carpi68
Copy link

Carpi68 commented Apr 11, 2016

@ErikEJ Thank you! This may be a stupid question, but how can I use a NuGet feed with a WPF project?

@ErikEJ
Copy link
Contributor

ErikEJ commented Apr 11, 2016

@Carpi68 Just configure the NuGet client to use the source above (you are already using NuGet if you use EF Core)

@Carpi68
Copy link

Carpi68 commented Apr 12, 2016

@ErikEJ Yes, that's clear and my apology for asking stupid questions. I'm not too familiar with this task. So can you please also advise which packets I need to install via my Package Manager Console to update my EF7-rc1 to the myget/aspnetvnext? Please note: I'm not developing an ASP.NET application. I'm using EF7 for a WPF application.

@ErikEJ
Copy link
Contributor

ErikEJ commented Apr 12, 2016

@Carpi68
Copy link

Carpi68 commented Apr 12, 2016

@ErikEJ I need to bother you again. I successfully upgraded to the nightly build (20539) and my project is compiling like a charm. But when I try to add a new migration I'm getting this failure The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: c:\Users\Projects\MyProject\packages\Microsoft.EntityFrameworkCore.Commands.1.0.0-rc2-20539\tools\OperationHandlers.cs(35) : ; expected. Do you think it makes sense to try anything else or do you recommend to return to the rc1? Note: I deleted any existing migration, so I do not expect any issue with legacy data.

Here's the complete output:
Add-Migration -Name InitialMigration
The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: c:\Users\Projects\MyProject\packages\Microsoft.EntityFrameworkCore.Commands.1.0.0-rc2-20539\tools\OperationHandlers.cs(35) : ; expected

c:\Users\Projects\MyProject\packages\Microsoft.EntityFrameworkCore.Commands.1.0.0-rc2-20539\tools\OperationHandlers.cs(34) :

c:\Users\Projects\MyProject\packages\Microsoft.EntityFrameworkCore.Commands.1.0.0-rc2-20539\tools\OperationHandlers.cs(35) : >>> public virtual int Version => 0;

c:\Users\Projects\MyProject\packages\Microsoft.EntityFrameworkCore.Commands.1.0.0-rc2-20539\tools\OperationHandlers.cs(36) :

@maumar
Copy link
Contributor

maumar commented Apr 18, 2016

@Nikhil1292 I was able to run your scenario, slightly modified:

_dbContext.Comments
.Include(c => c.Post)
.Where(c => c.Post.Blog.BlogId == true)
.ToList();

but it now yields incorrect results - I filed #5103 to track this

@maumar
Copy link
Contributor

maumar commented Apr 18, 2016

@RiyasMeeran could you provide some more information about your scenario? specifically the DbContext code and entities used (Product, Company, Project and the root entity that you are trying to include)

@maumar
Copy link
Contributor

maumar commented Apr 18, 2016

reopening for investigation

@maumar maumar reopened this Apr 18, 2016
@rowanmiller
Copy link
Contributor

@maumar can we close this one out?

@rowanmiller rowanmiller removed this from the 1.0.0 milestone May 4, 2016
@maumar
Copy link
Contributor

maumar commented May 4, 2016

@rowanmiller yes, first example has been fixed and there is no response from the second customer about details of his scenario.

@maumar maumar closed this as completed May 4, 2016
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests