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

  1. Use a simple member-access lambda over the entity parameter: SetProperty(e => e.Name, value) where Name is a mapped scalar property.
  2. Ensure the property referenced is a mapped IProperty on the target entity (not a computed/unmapped field).
  3. Avoid projecting to anonymous types before ExecuteUpdate; operate on the entity DbSet directly.
  4. 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

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


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/35013c61d4c4d155. Report an issue: GitHub.