question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Count with Take or Skip throws InvalidCastException

See original GitHub issue

Query throws InvalidCastException when Take or Skip is used after Select which includes ternary expression with join (in the sample the condition doesn’t really make sense since Country doesn’t have type hierarchy registered, but effect is the same).

This seems to be contination of https://github.com/aspnet/EntityFrameworkCore/issues/16722

context.Cities
    .Select(c => new
    {
        Name = c.Name,
        Country = c.Country is Country ?
            new
            {
                Name = c.Country.Name,
            } :
            null,
    })
    .Take(20)
    .Count();
Unhandled exception. System.InvalidCastException: Unable to cast object of type 'Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlFunctionExpression' to type 'System.Linq.Expressions.ConstantExpression'.
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.GetProjectionIndex(ProjectionBindingExpression projectionBindingExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
   at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   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 System.Linq.Queryable.Count[TSource](IQueryable`1 source)
   at test_efcore_count.Program.Main(String[] args) in D:\Projects\test-efcore-count\test-efcore-count\Program.cs:line 112
   at test_efcore_count.Program.<Main>(String[] args)

Steps to reproduce

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace test_efcore_count
{
    class Country
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public ICollection<City> Cities { get; set; }
    }

    class City
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public Country Country { get; set; }
        public int CountryId { get; set; }
    }

    class MapContext : DbContext
    {
        public MapContext(DbContextOptions<MapContext> options)
            : base(options)
        { }

        public DbSet<Country> Countries { get; set; }
        public DbSet<City> Cities { get; set; }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            var serviceCollection = new ServiceCollection();
            serviceCollection.AddLogging(x => x.AddConsole());
            serviceCollection.AddDbContext<MapContext>(dbContextBuilder =>
            {
                dbContextBuilder.UseSqlServer("Server=.;Initial Catalog=test-efcore-count;Integrated Security=True");
            });

            using var serviceProvider = serviceCollection.BuildServiceProvider();

            Console.WriteLine("Preparing database..");

            using (var scope = serviceProvider.CreateScope())
            using (var context = scope.ServiceProvider.GetRequiredService<MapContext>())
            {
                await context.Database.EnsureDeletedAsync();
                await context.Database.EnsureCreatedAsync();
            }

            Console.WriteLine("Inserting data..");

            using (var scope = serviceProvider.CreateScope())
            using (var context = scope.ServiceProvider.GetRequiredService<MapContext>())
            {
                context.Countries.Add(new Country()
                {
                    Name = "Czech Republic",
                    Cities = new[]
                    {
                        new City() { Name = "Prague" },
                        new City() { Name = "Brno" },
                    }
                });
                context.Countries.Add(new Country()
                {
                    Name = "Spain",
                    Cities = new[]
                    {
                        new City() { Name = "Madrid" },
                        new City() { Name = "Barcelona" },
                    }
                });

                await context.SaveChangesAsync();
            }

            Console.WriteLine("Printing data..");

            using (var scope = serviceProvider.CreateScope())
            using (var context = scope.ServiceProvider.GetRequiredService<MapContext>())
            {
                var query = context.Cities
                    .Select(c => new
                    {
                        Name = c.Name,
                        Country = c.Country is Country ?
                            new
                            {
                                Name = c.Country.Name,
                            } :
                            null,
                    });

                // works
                var list = query.Take(20).ToArray();
                foreach (var item in list)
                {
                    Console.WriteLine($"{item.Name} in {item.Country.Name}");
                }

                // error
                var total = query.Take(20).Count();
                Console.WriteLine($"Database contains {total} cities");
            }
        }
    }
}

Further technical details

EF Core version: 3.0.0 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET Core 3.0 Operating system: Windows 10 1903 IDE: Visual Studio 2019 16.3.4

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

8reactions
sgabler-solyticcommented, Jun 9, 2020

Facing the same issue in EF Core 3.1.4. Did you happen to find a workaround @TsengSR?

@ajcvickers wrote:

Note from triage: this is a client evaluation case where we could throw a better exception in the future.

But @Kukkimonsuta had this question about that statement:

Could you please elaborate why this query is working with ToArray, but it’s not supposed to work with Count? These queries were working in 2.x and it is causing us significant pain when porting to 3.0 since we are using them for paging and discovery of number of possible pages with upper limit.

If the maintainers find some time to reply, I’d like to understand if this is currently a bug in EF Core, or if it’s actually working as intended. Thank you

1reaction
rojicommented, Oct 16, 2020

I’ve taken another look at this, and it seems to be resolved in EF Core 5.0 - please try using the recently-released 5.0.0-rc2.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - SingleResult<myObject> .ToList or .Count throws an ...
As a single element you can't convert it to a list of more than one element or count how many elements it has....
Read more >
C# ienumerable.count() raises an invalidcastexception
I just found out than in the code of the Count() method it cast from IEnumerable to ICollection. (ICollection<tsource> collection = source as ......
Read more >
System.InvalidCastException: Unable to cast object of type ...
HI, I received this message : System.InvalidCastException: Unable to cast object of type 'System.Int64' to type 'System.Int32'.
Read more >
Casting vs “as” – embracing exceptions
If the actual value of the expression is a non-null reference to an incompatible type, casting will throw an InvalidCastException whereas the " ......
Read more >
SSRS 2014 + Report Manager Error + System. ...
Hi All - I'm getting a very strange error in SSRS 2014. Both Report Manager and Reporting Service are now unavailable.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found