dotnet/efcore · error · InvalidOperationException
InvalidPropertyInSetProperty
InvalidPropertyInSetProperty
Error message
The following lambda argument to 'SetProperty' does not represent a valid property to be set: '{propertyExpression}'. What it means
Thrown on the ExecuteUpdate pushdown path (PushdownWithPkInnerJoinPredicate, used when the provider cannot natively translate the update) when the first SetProperty lambda's property selector is not a recognizable member access binding to an entity shaper. The pushdown rewrite needs to locate the entity and its primary key from the property selector; if the lambda does not represent a valid property, the rewrite fails.
Source
Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs:86
// WHERE Id IN (SELECT ...) syntax), since we allow projecting out to arbitrary shapes (e.g. anonymous types) before the
// ExecuteUpdate.
// To rewrite the query, we need to know the primary key properties, which requires getting the entity type.
// Although there may be several entity types involved, we've already verified that they all map to the same table.
// Since we don't support table sharing of multiple entity types with different keys, simply get the entity type and key from
// the first property selector.
// The following mechanism for extracting the entity type from property selectors only supports simple member access,
// EF.Function, etc. We also unwrap casts to interface/base class (#29618). Note that owned IncludeExpressions have already
// been pruned from the source before remapping the lambda (#28727).
var firstPropertySelector = setters[0].PropertySelector;
if (!IsMemberAccess(
RemapLambdaBody(source, firstPropertySelector).UnwrapTypeConversion(out _),
RelationalDependencies.Model,
out var baseExpression)
|| _sqlTranslator.TranslateProjection(baseExpression) is not StructuralTypeShaperExpression shaper)
{
throw new InvalidOperationException(RelationalStrings.InvalidPropertyInSetProperty(firstPropertySelector));
}
// TODO: #36336
if (shaper.StructuralType is not IEntityType entityType)
{
throw new InvalidOperationException(
RelationalStrings.ExecuteUpdateSubqueryNotSupportedOverComplexTypes(shaper.StructuralType.DisplayName()));
}
if (entityType.FindPrimaryKey() is not { } pk)
{
throw new InvalidOperationException(
RelationalStrings.ExecuteOperationOnKeylessEntityTypeWithUnsupportedOperator(
nameof(EntityFrameworkQueryableExtensions.ExecuteUpdate),
entityType.DisplayName()));
}
// Generate the INNER JOIN around the original query, on the PK properties.View on GitHub (pinned to dbf9771522)
Solutions
- Use a simple member-access lambda over the entity parameter: SetProperty(e => e.Name, value) where Name is a mapped scalar property.
- Ensure the property referenced is a mapped IProperty on the target entity (not a computed/unmapped field).
- Avoid projecting to anonymous types before ExecuteUpdate; operate on the entity DbSet directly.
- If setting a value derived from another column, reference the entity property and compute the value in the value selector, not the property selector.
Example fix
// before
await db.Blogs.Where(b => b.Id == id)
.ExecuteUpdateAsync(s => s.SetProperty(b => 5, b => b.Rating));
// after - property selector must be a mapped property of the entity
await db.Blogs.Where(b => b.Id == id)
.ExecuteUpdateAsync(s => s.SetProperty(b => b.Rating, b => 5)); Defensive patterns
Strategy: validation
Validate before calling
static bool IsValidSetPropertySelector(LambdaExpression selector, IEntityType et)
=> selector.Body is MemberExpression me
&& me.Expression == selector.Parameters[0]
&& et.FindProperty(me.Member.Name) is not null;
var selector = (LambdaExpression)setters[0].PropertySelector;
if (!IsValidSetPropertySelector(selector, entityType))
throw new InvalidOperationException("SetProperty selector must be a simple mapped property of the entity."); Type guard
static bool IsEntityMemberAccess<T>(Expression<Func<T, object?>> selector)
=> selector.Body is MemberExpression { Expression: ParameterExpression };
// usage guard before ExecuteUpdate
if (!IsEntityMemberAccess((Expression<Func<Blog, object?>>)(b => b.Name))) throw new ArgumentException("bad selector"); Prevention
- Always use simple entity-parameter member access in SetProperty selectors.
- Reference only mapped scalar IProperty names in SetProperty.
- Avoid anonymous/projection selectors before ExecuteUpdate.
- Put computed logic in the value selector, not the property selector.
When it happens
Trigger: Calling ExecuteUpdate where SetProperty receives a lambda that is not simple entity member access - e.g. SetProperty((c => 5), ...), SetProperty(c => c.CalculatedField, ...) where CalculatedField is not a mapped property, or a lambda referencing a projection/anonymous member instead of the entity parameter.
Common situations: Trying to set a computed/non-mapped field; passing a constant or expression instead of a property selector; composing SetProperty over a Select that changed the parameter type; typos in member names.
Related errors
- ExecuteUpdateSubqueryNotSupportedOverComplexTypes
- ExecuteOperationOnOwnedJsonIsNotSupported
- ExecuteOperationOnTPT
- ExecuteOperationOnTPC
- ExecuteUpdateDeleteOnEntityNotMappedToTable
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/35013c61d4c4d155.
Report an issue: GitHub.