Closed mgrosperrin closed 1 year ago
Minimal repro with 7.0.4:
await using var ctx = new BlogContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();
ctx.Entities.ExecuteUpdate(updates => updates.SetProperty(e => e.Name, e => e.Name));
class BlogContext : DbContext
{
public DbSet<Blog> Entities { 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 Blog
{
public int Id { get; set; }
public string Name { get; set; }
public BlogDetails Owned { get; set; }
}
[Owned]
public class BlogDetails
{
public string Value { get; set; }
}
Exception:
Unhandled exception. System.InvalidOperationException: The LINQ expression 'DbSet<Blog>()
.Select(b => IncludeExpression(
EntityExpression:
b,
NavigationExpression:
EF.Property<BlogDetails>(b, "Owned"), Owned)
)
.ExecuteUpdate(updates => updates.SetProperty<string>(
propertyExpression: e => e.Name,
valueExpression: e => e.Name))' could not be translated. Additional information: The following 'SetProperty' failed to translate: 'SetProperty(e => e.Name, e => e.Name)'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
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__DisplayClass9_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.ExecuteUpdate[TSource](IQueryable`1 source, Expression`1 setPropertyCalls)
at Program.<Main>$(String[] args) in /home/roji/projects/test/Program.cs:line 13
at Program.<Main>$(String[] args) in /home/roji/projects/test/Program.cs:line 13
at Program.<Main>(String[] args)
@roji
This works:
await context.Entities.ExecuteUpdateAsync(x => x.SetProperty(e => e.Name, "X"));
And this works:
var newVal = "X";
await context.Entities.ExecuteUpdateAsync(x => x.SetProperty(e => e.Name, newVal));
But this throws:
await context.Entities.ExecuteUpdateAsync(x => x.SetProperty(e => e.Name, e => e.Name));
@ajcvickers thanks, I'll look into this soon. I may have a hunch.
Submitted #30571, definitely a good candidate for patching.
When calling ExecuteUpdate to conditionnaly update an entity with owned subentity, an
System.InvalidOperationException
is thrown.Repro code here: https://github.com/mgrosperrin/repro_issues/tree/efcore-executeupdate-owned-entity My goal is to update the property only if the user provide a value and to use the current value otherwise (to response to a PATCH API call).
The code in the repo use the null coalescing operator, but I have the same exception with the following code:
updates.SetProperty(e => e.Name, e => e.Name)
Include stack traces
Include the full exception message and stack trace for any exception you encounter.
Use triple-tick fences for stack traces. For example:
Include provider and version information
EF Core version: 7.0.4 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 7.0 Operating system: Windows 11 IDE: Visual Studio 2022 17.5.2