dotnet/efcore · error · InvalidOperationException

The following lambda argument to 'SetProperty' does not repr

Error message

The following lambda argument to 'SetProperty' does not represent a valid property to be set: '{propertyExpression}'.

What it means

TranslateSetters uses the first SetProperty lambda to identify the entity being updated. It remaps the lambda body, unwraps type conversions, and requires IsMemberAccess to succeed and the translated projection to be a StructuralTypeShaperExpression. If the lambda is not a simple member access on the entity (or unwraps to something other than the entity shaper), this throw fires: EF cannot tell which column to set.

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 3a2006ef56)

Solutions

  1. Make each SetProperty lambda a simple member-access on the entity parameter: SetProperty(e => e.Property, value).
  2. For computed updates, compute the value outside and pass a constant, or use raw SQL.
  3. Ensure the lambda's source parameter is the entity being updated and that the member is a mapped property of that entity.
  4. Avoid casts to interfaces/base classes inside the property selector unless they unwrap cleanly to the entity type.

Example fix

// before (non-member-access selector -> 599)
await db.Blogs.ExecuteUpdateAsync(s => s
    .SetProperty(b => 5, _ => 5)
    .SetProperty(b => b.Title.ToUpper(), _ => "X"));
// after (simple member access on mapped properties)
await db.Blogs.ExecuteUpdateAsync(s => s
    .SetProperty(b => b.Status, 5)
    .SetProperty(b => b.Title, "X"));
Defensive patterns

Strategy: validation

Validate before calling

// Validate that a SetProperty selector is a simple member access on the entity parameter.
static bool IsSimpleMemberAccess<T>(Expression<Func<T, object?>> selector)
{
    var body = selector.Body;
    if (body is UnaryExpression u && u.NodeType == ExpressionType.Convert)
        body = u.Operand;
    return body is MemberExpression me && me.Expression == selector.Parameters[0];
}

if (!IsSimpleMemberAccess((Blog b) => b.Title))
    throw new InvalidOperationException("SetProperty selector must be a simple mapped member access on the entity.");

Prevention

When it happens

Trigger: context.Blogs.ExecuteUpdate(s => s.SetProperty(b => 5, value)) (constant); SetProperty(b => b.NotAMappedProperty, ...); SetProperty(b => someExternalValue, ...); SetProperty with a lambda that performs computation (b => b.Count + 1) instead of pure member access; a lambda cast to an interface/base class that unwraps to a non-shaper.

Common situations: Using computed expressions inside SetProperty; copying a Select lambda into SetProperty; referencing a static or local instead of an entity member; refactoring entities behind interfaces (#29618 edge cases).

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/d497a520a5455929. Report an issue: GitHub.