Skip to content

System.InvalidOperationException: 'The LINQ expression 'c' could not be translated #3672

@tomrus88

Description

@tomrus88

After upgrading my project from .NET 9 to .NET 10 I'm getting this exception

System.InvalidOperationException: 'The LINQ expression 'c' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
Minimal repro

csproj (broken)

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.0" />
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="10.0.0" />
  </ItemGroup>
</Project>

csproj (working) with .NET 10 RC1 packages code still works fine, just like it does with .NET 9

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.0-rc.1.25451.107" />
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime" Version="10.0.0-rc.1" />
  </ItemGroup>
</Project>

Program.cs

using Microsoft.EntityFrameworkCore;
using NodaTime;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace SqlTranslationBug
{
    public class CloseGameRequest
    {
        public int GameId { get; set; }
        public int ServerId { get; set; }
    }

    internal class Program
    {
        static async Task Main(string[] args)
        {
            await using var ctx = new MyDbContext();

            await ctx.Database.EnsureDeletedAsync();
            await ctx.Database.EnsureCreatedAsync();

            Game game = new Game { Name = "test", GameId = 1, ServerId = 2 };

            ctx.Characters.Add(new() { Id = 1, Name = "char1", Game = game, GameEnterTime = SystemClock.Instance.GetCurrentInstant() });
            ctx.Characters.Add(new() { Id = 2, Name = "char2", Game = game, GameEnterTime = SystemClock.Instance.GetCurrentInstant() });
            await ctx.SaveChangesAsync();

            CloseGameRequest request = new CloseGameRequest() { GameId = 1, ServerId = 2 };

            await ctx.Characters
                .Where(o => o.Game != null && o.Game.GameId == request.GameId && o.Game.ServerId == request.ServerId)
                .ExecuteUpdateAsync(p => p
                    .SetProperty(f => f.GameName, (string)null)
                    .SetProperty(f => f.PlayTime, o => o.PlayTime + (SystemClock.Instance.GetCurrentInstant() -
                                       (o.GameEnterTime ?? SystemClock.Instance.GetCurrentInstant())))
                    .SetProperty(f => f.GameEnterTime, (Instant?)null)
                    .SetProperty(f => f.LastSaveTime, SystemClock.Instance.GetCurrentInstant())
                );

            Console.WriteLine("Done");

            Console.ReadLine();
        }
    }

    public class MyDbContext : DbContext
    {
        public DbSet<Character> Characters { get; set; }
        public DbSet<Game> Games { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseNpgsql(@"Host=localhost:5432;Database=testing;Username=postgres;Password=qwerty;", o => o
                .SetPostgresVersion(14, 15)
                .UseNodaTime()
            );

            base.OnConfiguring(optionsBuilder);
        }
    }

    public class Character
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [MaxLength(64)]
        [Column(TypeName = "citext")]
        public string Name { get; set; }

        [ForeignKey("Game")]
        [MaxLength(60)]
        public string GameName { get; set; }
        public Duration PlayTime { get; set; } = Duration.Zero;
        public Instant? GameEnterTime { get; set; } = Instant.MinValue;
        public Instant LastSaveTime { get; set; } = Instant.MinValue;
        public virtual Game Game { get; set; }
    }

    public class Game
    {
        [MaxLength(60)]
        [Key]
        [Column(TypeName = "citext")]
        public string Name { get; set; }

        public int GameId { get; set; }
        public int ServerId { get; set; }
    }
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions