ExecuteUpdate passed a complex type instance throws when using existing table values in the update
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
This is fine:
```C#
await context.Foos.ExecuteUpdateAsync(s => s.SetProperty(e => e.Address, new Address("B", "A")));
```
This throws:
```C#
await context.Foos.ExecuteUpdateAsync(s => s.SetProperty(e => e.Address, b => new Address(b.Address.Line2, "B")));
```
```
System.InvalidOperationException: The LINQ expression 'DbSet()
.ExecuteUpdate(s => s.SetProperty
propertyExpression: e => e.Address,
valueExpression: b => new Address(
b.Address.Line2,
"B"
)))' could not be translated. Additional information: The following lambda argument to 'SetProperty' does not represent a valid value: 'b => new Address(
b.Address.Line2,
"B"
)'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
```
Full code:
```C#
using (var context = new SomeDbContext())
{
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
context.AddRange(new Foo { Address = new Address("A", "B") });
await context.SaveChangesAsync();
}
using (var context = new SomeDbContext())
{
// Works
await context.Foos.ExecuteUpdateAsync(s => s.SetProperty(e => e.Address, new Address("B", "A")));
// Throws
await context.Foos.ExecuteUpdateAsync(s => s.SetProperty(e => e.Address, b => new Address(b.Address.Line2, "B")));
}
public class SomeDbContext : DbContext
{
public DbSet Foos => Set();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer(@"Data Source=localhost;Database=One;Integrated Security=True;Trust Server Certificate=True")
.LogTo(Console.WriteLine)
.EnableSensitiveDataLogging();
}
public class Foo
{
public int Id { get; set; }
public required Address Address { get; set; }
}
[ComplexType]
public record Address(string Line1, string Line2);
```
Contributor guide
Assessment
This issue has not been assessed yet.