dotnet / dotnet/efcore

Better error message with ExecuteUpdate

Open
#37,862 2 comments 0 reactions 0 assignees View on GitHub
area-bulkupdate customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

### What problem are you trying to solve?

When executing a `ExecuteUpdateAsync` and using some navigation property that is not included in the source query, I got a confusing error message.
```cs
List deviationIds = [1, 2, 3];
await ctx.RingOperation
.Where(ro => deviationIds.Contains(ro.Deviation!.ServerKey!.Value))
.ExecuteUpdateAsync(setters => setters
.SetProperty(ro => ro.DeviationId, ro => ro.Deviation!.ServerKey)
);
```
This throws the exception

> ArgumentException: Property 'System.Nullable\`1[System.Int32] DeviationId' is not defined for type 'Microsoft.EntityFrameworkCore.Query.TransparentIdentifierFactory+TransparentIdentifier\`2[RingOperation,Deviation]' (Parameter 'property')

I know now that I can rewrite the query into
```cs
await ctx.RingOperation
.Where(ro => deviationIds.Contains(ro.Deviation!.ServerKey!.Value))
.Select(ro => new { ro, ro.Deviation!.ServerKey })
.ExecuteUpdateAsync(setters => setters
.SetProperty(o => o.ro.DeviationId, o => o.ServerKey)
);
```
But from the error message, this is not at all obvious.

Minimal DbContext & Models

```cs
public partial class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions options)
: base(options)
{
}

public DbSet Deviation { get; set; } = default!;
public DbSet RingOperation { get; set; } = default!;

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasKey(d => d.DeviationID);

modelBuilder.Entity()
.HasKey(ro => ro.RingOperationId);

modelBuilder.Entity()
.HasOne(ro => ro.Deviation)
.WithMany()
.HasForeignKey(ro => ro.DeviationId)
.HasPrincipalKey(d => d.DeviationID);
}
}

public class Deviation
{
public int DeviationID { get; set; }
public int? ServerKey { get; set; }
}

public class RingOperation
{
public int RingOperationId { get; set; }
public int? DeviationId { get; set; }
public Deviation? Deviation { get; set; }
}
```

### Describe the solution you'd like

A better error message explaining that went wrong, and maybe a suggestion of how to fix it.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.