dotnet/efcore · error · NotImplementedException

ListInit: lifted statements

Error message

ListInit: lifted statements

What it means

Symmetric to the MemberInit lifted-statements case but for ListInitExpression: if translating a collection-initializer element produces lifted statements, the translator cannot position those statements after the instantiation (it normally lifts to before), so it throws NotImplementedException("ListInit: lifted statements").

Source

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

            // C# collection initialization syntax only works when Add is called on an IEnumerable, but LINQ supports arbitrary add
            // methods. Skip these, we'll add them later outside the initializer
            if (!listInit.NewExpression.Type.IsAssignableTo(typeof(IEnumerable))
                || listInit.Initializers.Any(e => e.AddMethod.Name != "Add" || e.Arguments.Count != 1))
            {
                incompatibleListBindings ??= [];
                incompatibleListBindings.Add(initializer);
                continue;
            }

            var liftedStatementsPosition = _liftedState.Statements.Count;

            VisitElementInit(initializer);

            initializerExpressions.Add((ExpressionSyntax)Result!);

            if (_liftedState.Statements.Count > liftedStatementsPosition)
            {
                throw new NotImplementedException("ListInit: lifted statements");
            }
        }

        if (incompatibleListBindings is not null)
        {
            // TODO: This requires lifting statements to *after* the instantiation - we usually lift to before.
            // This is problematic: if such an expression is passed as an argument to a method, there's no way to faithfully translate it
            // while preserving evaluation order.
            throw new NotImplementedException("ListInit: incompatible ElementInit");
        }

        Result = objectCreation.WithInitializer(
            InitializerExpression(
                SyntaxKind.CollectionInitializerExpression,
                SeparatedList(initializerExpressions)));

        return listInit;
    }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Compute element values into locals first, then add them.
  2. Use side-effect-free element expressions (constants, parameter reads).
  3. Construct the collection and call Add explicitly instead of using an initializer.

Example fix

// before
var li = Expression.ListInit(newList, Expression.ElementInit(add, MethodCall()));
// after
// compute tmp = MethodCall() first, then list init with tmp
Defensive patterns

Strategy: validation

Validate before calling

// Flag ListInit elements that have side effects
protected override Expression VisitListInit(ListInitExpression li) {
    if (li.Initializers.Any(e => e.Arguments.Any(a => new SideEffectDetector().HasSideEffects(a)))) Found = true;
    return li;
}

Prevention

When it happens

Trigger: A collection initializer element expression with side effects requiring lifting, e.g. new List<T> { SomeMethod() } where the element needs hoisting.

Common situations: Collection initializers in precompiled queries where elements involve method calls or other side-effecting expressions.

Related errors


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