dotnet/efcore · error · NotSupportedException

Anonymous type creation without members

Error message

Anonymous type creation without members

What it means

Thrown by LinqToCSharpSyntaxTranslator.VisitNew when node.Type.IsAnonymousType() is true but node.Members is null. To render an anonymous-object-creation expression the translator needs the Members collection (property names) to build the AnonymousObjectMemberDeclarator initializers; a NewExpression for an anonymous type without members has no member-name information and cannot be emitted as C#.

Solutions

  1. Construct the NewExpression with the members overload, supplying the property MemberInfos that correspond positionally to the constructor arguments: Expression.New(constructor, args, members).
  2. If you cannot supply members, switch from an anonymous type to a named DTO whose constructor maps cleanly.
  3. When copying/transforming trees, propagate node.Members through the visitor rather than rebuilding NewExpression without it.

Example fix

// before — anonymous NewExpression built without members
var ctor = anonType.GetConstructors()[0];
var newExpr = Expression.New(
    ctor,
    new[] { idArg, nameArg }); // node.Members is null -> throws

// after — pass the property member infos positionally
var props = anonType.GetProperties();
var newExpr = Expression.New(
    ctor,
    new[] { idArg, nameArg },
    props);
Defensive patterns

Strategy: validation

Validate before calling

// Reject anonymous-type NewExpressions that lack the Members collection.
using System.Linq.Expressions;
using System.Runtime.CompilerServices;

bool IsAnonymous(Type t)
    => t is not null
       && Attribute.IsDefined(t, typeof(CompilerGeneratedAttribute))
       && t.Name.Contains("AnonymousType");

bool HasAnonymousNewWithoutMembers(Expression e)
{
    bool bad = false;
    new NewChecker(n =>
    {
        if (IsAnonymous(n.Type) && n.Members is null) bad = true;
    }).Visit(e);
    return bad;
}

class NewChecker(Action<NewExpression> onNew) : ExpressionVisitor
{
    protected override Expression VisitNew(NewExpression n) { onNew(n); return base.VisitNew(n); }
}

Type guard

static bool IsAnonymousNewWithMembers(NewExpression n)
    => !IsAnonymous(n.Type) || n.Members is not null;

Prevention

When it happens

Trigger: An expression tree constructs an anonymous type via Expression.New with a constructor but no members list (e.g. constructed manually with Expression.New(constructorInfo, args) and no member-info array), and the resulting Type is detected as anonymous.

Common situations: Hand-built expression trees that mimic anonymous-type construction without supplying the Members array (which the C# compiler always provides when compiling real anonymous-type literals); serialization/deserialization round-trips that drop the Members collection; refactoring that stripped member metadata.

Related errors


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

Appendix: source

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

        Result = _g.ArrayCreationExpression(elementType, expressions);

        return newArray;
    }

    /// <inheritdoc />
    protected override Expression VisitNew(NewExpression node)
    {
        using var _ = ChangeContext(ExpressionContext.Expression);

        var arguments = node.Constructor is null
            ? []
            : TranslateMethodArguments(node.Constructor.GetParameters(), node.Arguments);

        if (node.Type.IsAnonymousType())
        {
            if (node.Members is null)
            {
                throw new NotSupportedException("Anonymous type creation without members");
            }

            Result = AnonymousObjectCreationExpression(
                SeparatedList(
                    arguments.Select((arg, i) =>
                            AnonymousObjectMemberDeclarator(NameEquals(node.Members[i].Name), arg.Expression))
                        .ToArray()));

            return node;
        }

        // If the constructor isn't public, or it has required properties and the constructor doesn't have [SetsRequiredMembers], we can't
        // just generate a regular instantiation expression (won't compile). Generate an unsafe accessor instead.
        if (node.Constructor is { } constructor
            && (!constructor.IsPublic
                || (node.Type.GetCustomAttribute<RequiredMemberAttribute>() is not null
                    && constructor.GetCustomAttribute<SetsRequiredMembersAttribute>() is null)))
        {

View on GitHub (pinned to 3a2006ef56)