Skip to content

The order of ExecuteUpdate setters is not preserved #35361

@roji

Description

@roji

For the following ExecuteUpdate:

await context.Posts
    .ExecuteUpdateAsync(s => s
        .SetProperty(b => b.Content, b => b.Content + " ( Title was " + b.Title  + ")")
        .SetProperty(b => b.Title, b => "New Title"));

... we generate the following SQL:

UPDATE [p]
SET [p].[Title] = N'New Title',
        [p].[Content] = [p].[Content] + N' ( Title was ' + [p].[Title] + N')'
FROM [Posts] AS [p]

Note that the SQL order of the setters is reversed; this is important, as there can be a dependency between the setters. We should preserve the original LINQ ordering.

Originally flagged in PomeloFoundation/Pomelo.EntityFrameworkCore.MySql#1776

Full repro
await using var context = new BlogContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();

await context.Posts
    .ExecuteUpdateAsync(s => s
        .SetProperty(b => b.Content, b => b.Content + " ( Title was " + b.Title  + ")")
        .SetProperty(b => b.Title, b => "New Title"));

public class BlogContext : DbContext
{
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseSqlServer("Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false")
            .LogTo(Console.WriteLine, LogLevel.Information)
            .EnableSensitiveDataLogging();
}

public class Post
{
    public int Id { get; set; }
    public string Content { get; set; }
    public string Title { get; set; }
}

Metadata

Metadata

Assignees

Type

No fields configured for Bug.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions