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
- 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.
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
- 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.
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
- Can't translate method
- Compound assignment of private property not yet supported
- Private static field access
- Private static field assignment
- Unable to translate type
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)