Bug #118460 NullReferenceException when querying an entity with StartsWith
Submitted: 16 Jun 16:07 Modified: 17 Jun 5:05
Reporter: Manuel Zulian Email Updates:
Status: Analyzing Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:9.0.3 OS:Linux
Assigned to: MySQL Verification Team CPU Architecture:Any

[16 Jun 16:07] Manuel Zulian
Description:
When querying an entity with StartsWith the following error is raised. Not sure about the severity of this one as I still could not find a workaround. Tried with a different mysql provider and it works. Works on version 8 of the framework/packages etc...

Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.EntityFrameworkCore.Query.ExpressionExtensions.InferTypeMapping(SqlExpression[] expressions)
   at MySql.EntityFrameworkCore.Query.Internal.MySQLSqlExpressionFactory.ApplyTypeMappingOnCollate(MySQLCollateExpression collateExpression)
   at MySql.EntityFrameworkCore.Query.Internal.MySQLSqlExpressionFactory.ApplyNewTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping)
   at MySql.EntityFrameworkCore.Query.Internal.MySQLSqlExpressionFactory.ApplyTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressionFactory.ApplyDefaultTypeMapping(SqlExpression sqlExpression)
   at MySql.EntityFrameworkCore.Query.Internal.MySQLSqlExpressionFactory.Collate(SqlExpression valueExpression, String charset, String collation)
   at MySql.EntityFrameworkCore.Query.Expressions.Internal.MySQLStringComparisonMethodTranslator.Utf8Bin(SqlExpression value)
   at MySql.EntityFrameworkCore.Query.Expressions.Internal.MySQLStringComparisonMethodTranslator.<>c__DisplayClass11_0.<MakeStartsWithExpression>b__0()
   at MySql.EntityFrameworkCore.Query.Expressions.Internal.MySQLStringComparisonMethodTranslator.CreateExpressionForCaseSensitivity(StringComparison cmp, Func`1 ifCaseSensitive, Func`1 ifCaseInsensitive)
   at MySql.EntityFrameworkCore.Query.Expressions.Internal.MySQLStringComparisonMethodTranslator.MakeStartsWithExpression(SqlExpression target, SqlExpression prefix, SqlExpression stringComparison)
   at MySql.EntityFrameworkCore.Query.Internal.MySQLStringMethodTranslator.Translate(SqlExpression instance, MethodInfo method, IReadOnlyList`1 arguments, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Query.RelationalMethodCallTranslatorProvider.<>c__DisplayClass7_0.<Translate>b__0(IMethodCallTranslator t)
   at System.Linq.Enumerable.IteratorSelectIterator`2.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at Microsoft.EntityFrameworkCore.Query.RelationalMethodCallTranslatorProvider.Translate(IModel model, SqlExpression instance, MethodInfo method, IReadOnlyList`1 arguments, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression, Boolean applyDefaultTypeMapping)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorExpression[TResult](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__DisplayClass11_0`1.<ExecuteCore>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at Program.<Main>$(String[] args) in /home/manuel/RiderProjects/EFBug/EFBug/Program.cs:line 15

Example application provided later, running on a mysql container (version 9.1.0-1.el9).

Linux mint 22.1

dotnet 9.0.107

Connector version in the .csproj file at the end of the example

How to repeat:
using Microsoft.EntityFrameworkCore;

namespace EFBug;

public class Context : DbContext
{
    public Context(DbContextOptions<Context> options)
        : base(options)
    {
    }
    
    public DbSet<Image> Images { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Image>().ToTable("Image");

        modelBuilder.Entity<Image>().Property(e => e.Id)
            .HasColumnName("id")
            .HasColumnType("int(11)");

        modelBuilder.Entity<Image>().Property(e => e.CreatedAt)
            .HasColumnName("created_at")
            .HasColumnType("datetime");

        modelBuilder.Entity<Image>().Property(e => e.FileName)
            .IsRequired()
            .HasColumnName("file_name")
            .HasMaxLength(800)
            .HasColumnType("varchar(800)");

        modelBuilder.Entity<Image>().Property(e => e.FileUrl)
            .IsRequired()
            .HasColumnName("file_url")
            .HasMaxLength(8000)
            .HasColumnType("varchar(8000)");

        modelBuilder.Entity<Image>().Property(e => e.UpdatedAt)
            .HasColumnName("updated_at")
            .HasColumnType("datetime");
    }
}

====

namespace EFBug;

public class Image
{
    public Image()
    {
    }

    public int Id { get; set; }
    public string FileName { get; set; }
    public string FileUrl { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
}

===

// See https://aka.ms/new-console-template for more information

using EFBug;
using Microsoft.EntityFrameworkCore;

Console.WriteLine("Hello, World!");
var options = new DbContextOptionsBuilder<Context>()
    .UseMySQL("server=localhost;user=root;password=password;database=efbug;port=3306;")
    .Options;
var db = new Context(options);
db.Database.EnsureDeleted();
db.Database.EnsureCreated();

var images = db.Images.Where(i => i.FileName.StartsWith("test"));
Console.Write(images.Count());

===

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net9.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="MySql.EntityFrameworkCore" Version="9.0.3" />
    </ItemGroup>

</Project>