{"record":{"id":"d390a66862ed4158","repo":"dotnet/efcore","slug":"anonymous-type-creation-without-members","errorCode":null,"errorMessage":"Anonymous type creation without members","messagePattern":"Anonymous type creation without members","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs","lineNumber":2110,"sourceCode":"        Result = _g.ArrayCreationExpression(elementType, expressions);\n\n        return newArray;\n    }\n\n    /// <inheritdoc />\n    protected override Expression VisitNew(NewExpression node)\n    {\n        using var _ = ChangeContext(ExpressionContext.Expression);\n\n        var arguments = node.Constructor is null\n            ? []\n            : TranslateMethodArguments(node.Constructor.GetParameters(), node.Arguments);\n\n        if (node.Type.IsAnonymousType())\n        {\n            if (node.Members is null)\n            {\n                throw new NotSupportedException(\"Anonymous type creation without members\");\n            }\n\n            Result = AnonymousObjectCreationExpression(\n                SeparatedList(\n                    arguments.Select((arg, i) =>\n                            AnonymousObjectMemberDeclarator(NameEquals(node.Members[i].Name), arg.Expression))\n                        .ToArray()));\n\n            return node;\n        }\n\n        // If the constructor isn't public, or it has required properties and the constructor doesn't have [SetsRequiredMembers], we can't\n        // just generate a regular instantiation expression (won't compile). Generate an unsafe accessor instead.\n        if (node.Constructor is { } constructor\n            && (!constructor.IsPublic\n                || (node.Type.GetCustomAttribute<RequiredMemberAttribute>() is not null\n                    && constructor.GetCustomAttribute<SetsRequiredMembersAttribute>() is null)))\n        {","sourceCodeStart":2092,"sourceCodeEnd":2128,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs#L2092-L2128","documentation":"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#.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Construct the NewExpression with the members overload, supplying the property MemberInfos that correspond positionally to the constructor arguments: Expression.New(constructor, args, members).","If you cannot supply members, switch from an anonymous type to a named DTO whose constructor maps cleanly.","When copying/transforming trees, propagate node.Members through the visitor rather than rebuilding NewExpression without it."],"exampleFix":"// before — anonymous NewExpression built without members\nvar ctor = anonType.GetConstructors()[0];\nvar newExpr = Expression.New(\n    ctor,\n    new[] { idArg, nameArg }); // node.Members is null -> throws\n\n// after — pass the property member infos positionally\nvar props = anonType.GetProperties();\nvar newExpr = Expression.New(\n    ctor,\n    new[] { idArg, nameArg },\n    props);","handlingStrategy":"validation","validationCode":"// Reject anonymous-type NewExpressions that lack the Members collection.\nusing System.Linq.Expressions;\nusing System.Runtime.CompilerServices;\n\nbool IsAnonymous(Type t)\n    => t is not null\n       && Attribute.IsDefined(t, typeof(CompilerGeneratedAttribute))\n       && t.Name.Contains(\"AnonymousType\");\n\nbool HasAnonymousNewWithoutMembers(Expression e)\n{\n    bool bad = false;\n    new NewChecker(n =>\n    {\n        if (IsAnonymous(n.Type) && n.Members is null) bad = true;\n    }).Visit(e);\n    return bad;\n}\n\nclass NewChecker(Action<NewExpression> onNew) : ExpressionVisitor\n{\n    protected override Expression VisitNew(NewExpression n) { onNew(n); return base.VisitNew(n); }\n}","typeGuard":"static bool IsAnonymousNewWithMembers(NewExpression n)\n    => !IsAnonymous(n.Type) || n.Members is not null;","tryCatchPattern":null,"preventionTips":["Always construct anonymous-type NewExpression with the members overload (Expression.New(ctor, args, members)).","When transforming trees, propagate the Members collection through visitors rather than rebuilding NewExpression without it.","Prefer named DTOs when you cannot supply member metadata."],"tags":["ef-core","expression-trees","anonymous-types","new-expression","code-generation","reflection"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}