I'm trying to use the DbSet.ExecuteUpdate
method that was introduced in EF Core 7. When doing things the types way, so e.g.
dbContext
.Notifications
.Where(n => !n.Snoozed)
.ExecuteUpdate(s => s.SetProperty(
n => n.Snoozed,
n => true));
all is well.
Now I need to be able to update properties dynamically, so I would provide a Dictionary<string, object>
as input, and I need to update every property identified by its dictionary key and set it to the corresponding dictionary value.
Dictionary<string, object?> updates = new(); // filling omitted
foreach (var kvp in updates)
{
// set the property kvp.Key to value kvp.Value
}
How would I go about that? This is what I've come up with so far:
Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setExpression = _ => _;
foreach (var propertyValue in updates.Values)
{
var propertyExp = GetPropertyExpression<TEntity>(propertyValue.Key);
setExpression = c => c.SetProperty(propertyExp, _ => propertyValue.Value);
}
result.Result = await items.ExecuteUpdateAsync(setExpression).ConfigureAwait(false);
private static Func<TEntity, object> GetPropertyExpression<TEntity>(string propertyName)
{
var parameterExpression = Expression.Parameter(typeof(TEntity), "x");
var memberExpression = Expression.Property(parameterExpression, propertyName);
var lambda = Expression.Lambda<Func<TEntity, object>>(memberExpression, parameterExpression);
return lambda.Compile();
}
While this executes, I get an exception:
Unable to cast object of type 'System.Linq.Expressions.TypedParameterExpression' to type 'System.Linq.Expressions.LambdaExpression'