Query: Null TypeMapping in Sql Tree

See original GitHub issue

When using .Select to project into custom types you can run into this error when using the conditional operator. I’ve included a SSCE below, but the gist is this code here:

db.FirstEntities
    .Select(x => new FirstEntityModel
    {
        Id = x.Id,
        ThirdEntityId = x.ThirdEntity == null ? null : (int?)x.ThirdEntity.Id,
        SecondEntity = x.SecondEntity == null ? null : new SecondEntityModel()
    })
    .ToArray();

Interestingly, if I remove either the ThirdEntityId assignment or the SecondEntity assignment, there are no problems.

The full exception is:

System.InvalidOperationException
  HResult=0x80131509
  Message=The binary operator NotEqual is not defined for the types 'Microsoft.EntityFrameworkCore.Storage.ValueBuffer' and 'Microsoft.EntityFrameworkCore.Storage.ValueBuffer'.
  Source=System.Linq.Expressions
  StackTrace:
   at System.Linq.Expressions.Expression.GetEqualityComparisonOperator(ExpressionType binaryType, String opName, Expression left, Expression right, Boolean liftToNull)
   at System.Linq.Expressions.Expression.NotEqual(Expression left, Expression right, Boolean liftToNull, MethodInfo method)
   at System.Linq.Expressions.Expression.NotEqual(Expression left, Expression right)
   at Microsoft.EntityFrameworkCore.Query.Expressions.Internal.NullConditionalExpression.Reduce()
   at System.Linq.Expressions.Expression.ReduceAndCheck()
   at System.Linq.Expressions.Expression.ReduceExtensions()
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExtensionExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.MemberAssignmentRewriter..ctor(MemberAssignment binding, StackSpiller spiller, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.BindingRewriter.Create(MemberBinding binding, StackSpiller spiller, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteMemberInitExpression(Expression expr, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpression(Expression node, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.RewriteExpressionFreeTemps(Expression expression, Stack stack)
   at System.Linq.Expressions.Compiler.StackSpiller.Rewrite[T](Expression`1 lambda)
   at System.Linq.Expressions.Expression`1.Accept(StackSpiller spiller)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda)
   at System.Linq.Expressions.LambdaExpression.Compile()
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ProjectionShaper.Create(Shaper originalShaper, LambdaExpression materializer)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitSelectClause(SelectClause selectClause, QueryModel queryModel)
   at Remotion.Linq.Clauses.SelectClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel)
   at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](QueryModel queryModel)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger`1 logger, Type contextType)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass13_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 Remotion.Linq.QueryableBase`1.GetEnumerator()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at ConsoleApp2.Program.Main(String[] args) in C:\Users\Kirk\Documents\Visual Studio 2017\Projects\ConsoleApp2\ConsoleApp2\Program.cs:line 20

The full repro is to create a new .NET Core Console program, add Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.Sqlite and make this your main Program.cs file:

using System;
using System.Linq;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            var connection = new SqliteConnection("DataSource=:memory:");
            connection.Open();
            var options = new DbContextOptionsBuilder<TestDb>()
                .UseSqlite(connection)
                .Options;
            var db = new TestDb(options);
            db.Database.EnsureCreated();

            db.FirstEntities
                .Select(x => new FirstEntityModel
                {
                    Id = x.Id,
                    ThirdEntityId = x.ThirdEntity == null ? null : (int?)x.ThirdEntity.Id,
                    SecondEntity = x.SecondEntity == null ? null : new SecondEntityModel()
                })
                .ToArray();
        }
    }

    public class TestDb : DbContext
    {
        public DbSet<FirstEntity> FirstEntities { get; set; }
        public DbSet<SecondEntity> SecondEntities { get; set; }
        public DbSet<ThirdEntity> ThirdEntities { get; set; }

        public TestDb(DbContextOptions options) : base(options)
        {
        }
    }

    public class FirstEntity
    {
        public int Id { get; set; }
        public int? OtherId { get; set; }
        public int? SecondEntityId { get; set; }

        public ThirdEntity ThirdEntity { get; set; }
        public SecondEntity SecondEntity { get; set; }
    }

    public class SecondEntity
    {
        public int Id { get; set; }
        public int? OtherId { get; set; }
    }

    public class ThirdEntity
    {
        public int Id { get; set; }
        public int? FirstEntityId { get; set; }

        public FirstEntity FirstEntity { get; set; }
    }

    public class FirstEntityModel
    {
        public int Id { get; set; }
        public int? ThirdEntityId { get; set; }
        public SecondEntityModel SecondEntity { get; set; }
    }

    public class SecondEntityModel
    {
        public int Id { get; set; }
    }
}

Further technical details

EF Core version: 2.1.4 EF Core Sqlite version: 2.1.4 Database Provider: Microsoft.EntityFrameworkCore.Sqlite Operating system: Windows 10 IDE: Visual Studio 2017 15.8.8

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
divegacommented, Nov 2, 2018

Sorry for the dup! 😃

No worries @kswoll. We decided to use your issue to track this. Thanks for posting the workarounds.

0reactions
CliffordSpainhourcommented, Jun 12, 2020

I found a work around, but I don’t necessary like the solution. I’m not sure how this will affect performance.

In the Source Url Entity Class, I now always initialize the price as an empty POCO

    public class SiteProductSourceUrlEntity
    {
        public SiteProductSourceUrlEntity()
        {
            Price = new SiteProductPriceEntity();
        }

        public int Id { get; set; }
        public string Value { get; set; }
        
        public virtual SiteProductPriceEntity Price { get; set; }
        public int? VariationId { get; set; }
        public virtual SiteProductVariationEntity Variation { get; set; }
        public int SiteProductId { get; set; }
        public virtual SiteProductEntity SiteProduct { get; set; }
    }

I then changed the query to check with the price id instead of the price reference

var result = await context.SiteProducts.Where(x => x.Id == siteProductId).Select(p => new SiteProductModel
            {
                SourceUrls = p.SourceUrls.Select(e =>
                  new ProductSourceUrlModel
                  {
                      Id = e.Id,
                      Url = e.Value,
                      Price = e.Price.Id > 0 ? new ProductPriceModel
                      {
                          Id = e.Price.SiteProductSourceUrlId,
                          AmountMax = e.Price.AmountMax,
                          AmountMin = e.Price.AmountMin,
                          Currency = e.Price.Currency,
                          IsSale = e.Price.IsSale,
                          LastSeen = e.Price.LastSeen,
                          Merchant = e.Price.Merchant,
                          SourceUrl = e.Value,
                          Availability = e.Price.Availability
                      } : null,

                  }),
            }).FirstOrDefaultAsync();

Although this works, doing it this way has other negative affects. For example, I have to set any empty prices back to null in other queries using eager loading, otherwise it will try to save an empty price when persisting.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Null TypeMapping in Sql Tree"} from entity framework core ...
I have this linq select statment and I am getting this erro {"error":"Null TypeMapping in Sql Tree"} back. Ill put the code below...
Read more >
Query: "Null TypeMapping in Sql Tree" when projecting a ...
FirstOrDefault() }) exception: Null TypeMapping in Sql Tree D:\git\EntityFrameworkCore\src\EFCore.Relational\Query\PipeLine...
Read more >
EF Core 3 query property of nullable reference type as ...
The bug with throwing the "Null TypeMapping in Sql Tree" error by methods in LINQ query in EF Core 3 is fixed in...
Read more >
RelationalStrings.NullTypeMappingInSqlTree(Object) ...
Expression '{sqlExpression}' in the SQL tree does not have a type mapping assigned. C# Copy. public static string NullTypeMappingInSqlTree (object ...
Read more >
Getting {"error":"Null TypeMapping in Sql Tree"} from entity ...
Coding example for the question Getting {"error":"Null TypeMapping in Sql Tree"} from entity framework core using linq-entityframework core.
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