dotnet/efcore · error · NotImplementedException

MemberInit: lifted statements

Error message

MemberInit: lifted statements

What it means

While translating a MemberInitExpression (object initializer), if translating a member binding produces lifted statements (side-effecting sub-expressions that must be hoisted before the initializer), the translator cannot place them correctly and throws NotImplementedException("MemberInit: lifted statements").

Source

Thrown at src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs:2550

            if (binding is MemberListBinding listBinding
                && (!listBinding.Member.GetMemberType().IsAssignableTo(typeof(IEnumerable))
                    || listBinding.Initializers.Any(e => e.AddMethod.Name != "Add" || e.Arguments.Count != 1)))
            {
                incompatibleListBindings ??= [];
                incompatibleListBindings.Add(listBinding);
                continue;
            }

            var liftedStatementsPosition = _liftedState.Statements.Count;

            VisitMemberBinding(binding);

            initializerExpressions.Add((AssignmentExpressionSyntax)Result!);

            if (_liftedState.Statements.Count > liftedStatementsPosition)
            {
                // TODO: This is tricky because of the recursive nature of MemberMemberBinding
                throw new NotImplementedException("MemberInit: lifted statements");
            }
        }

        if (incompatibleListBindings is not null)
        {
            // TODO: Lift the instantiation and add extra statements to add the incompatible bindings after that
            throw new NotImplementedException("MemberInit: incompatible MemberListBinding");
        }

        Result = objectCreation.WithInitializer(
            InitializerExpression(
                SyntaxKind.ObjectInitializerExpression,
                SeparatedList<ExpressionSyntax>(initializerExpressions)));

        return memberInit;
    }

    /// <inheritdoc />

View on GitHub (pinned to dbf9771522)

Solutions

  1. Compute side-effecting member values into locals before the initializer.
  2. Simplify initializer member expressions to be side-effect-free (constants, parameter reads).
  3. Use a constructor plus explicit post-construction assignments instead of an initializer.

Example fix

// before
var init = Expression.MemberInit(newX, Expression.Bind(propA, MethodCall())); // lifts -> throws
// after
var tmp = Expression.Parameter(typeof(int), "a");
// assign tmp = MethodCall() before, then bind propA = tmp
Defensive patterns

Strategy: validation

Validate before calling

// Detect member-init bindings whose value translation would lift statements
public sealed class MemberInitSideEffectDetector : ExpressionVisitor {
    public bool Found;
    protected override Expression VisitMemberInit(MemberInitExpression mi) {
        foreach (var b in mi.Bindings) {
            if (b is MemberAssignment ma && new SideEffectDetector().HasSideEffects(ma.Expression)) Found = true;
        }
        return mi;
    }
}

Prevention

When it happens

Trigger: An object initializer where a member value expression has side effects requiring lifting, e.g. new X { A = SomeMethod() } where SomeMethod's translation lifts statements.

Common situations: Complex object initializers in precompiled queries with method-call member values or nested expressions that need hoisting.

Related errors


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