dotnet/efcore · error · InvalidOperationException

The type '{clrType}' is configured as a shared-type entity t

Error message

The type '{clrType}' is configured as a shared-type entity type, but the entity type name is not known. Ensure that CreateProxy is called on a DbSet created specifically for the shared-type entity type through use of a 'DbContext.Set' overload that accepts an entity type name.

What it means

Thrown by ProxyFactory.Create when a proxy is requested for a CLR type that the runtime model cannot resolve, but the type is registered as a shared-type entity type. Shared-type entity types (e.g. Dictionary<string, object> keyed by name) do not have a unique CLR type, so EF needs the explicit entity type name to find them.

Source

Thrown at src/EFCore.Proxies/Proxies/Internal/ProxyFactory.cs:42

    private readonly ProxyGenerator _generator = new();

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual object Create(
        DbContext context,
        Type type,
        params object[] constructorArguments)
    {
        var entityType = context.Model.FindRuntimeEntityType(type);
        if (entityType == null)
        {
            if (context.Model.IsShared(type))
            {
                throw new InvalidOperationException(ProxiesStrings.EntityTypeNotFoundShared(type.ShortDisplayName()));
            }

            throw new InvalidOperationException(CoreStrings.EntityTypeNotFound(type.ShortDisplayName()));
        }

        return CreateProxy(context, entityType, constructorArguments);
    }

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual Type CreateProxyType(
        IEntityType entityType)
        => _generator.ProxyBuilder.CreateClassProxyType(
            entityType.ClrType,

View on GitHub (pinned to dbf9771522)

Solutions

  1. Use the name-based DbSet overload: context.Set(typeof(T).Name, sharedTypeName) or DbContext.Set(Type, string) before calling CreateProxy, so EF knows which shared entity definition to use.
  2. Call CreateProxy via the IEntityType overload (CreateProxy(context, entityType, args)) after resolving the IEntityType by name, instead of the Type overload.
  3. Avoid using shared-type entity types with proxies; map a concrete CLR class for the join entity instead.

Example fix

// before
var proxy = context.CreateProxy<Dictionary<string, object>>(args); // throws

// after
var entityType = context.Model.FindEntityType("MySharedEntity")!;
var proxy = ((IInfrastructure<IServiceProvider>)context)
    .Instance.GetRequiredService<IProxyFactory>()
    .CreateProxy(context, entityType, args);
Defensive patterns

Strategy: validation

Validate before calling

IEntityType? ResolveSharedEntity(DbContext context, Type clrType, string name)
{
    var et = context.Model.FindEntityType(name)
             ?? context.Model.FindRuntimeEntityType(clrType);
    if (et == null && context.Model.IsShared(clrType))
        throw new InvalidOperationException($"Use Set(Type,'{name}') to resolve shared entity.");
    return et;
}

Type guard

static bool IsSharedTypeEntity(DbContext context, Type t)
    => context.Model.IsShared(t);

Prevention

When it happens

Trigger: Calling DbSet/ProxyFactory.Create with only a CLR type that is used as a shared type — context.Model.FindRuntimeEntityType(type) returns null and context.Model.IsShared(type) is true (ProxyFactory.cs:40-42). Common with the many-to-many join entity pattern using Dictionary<string,object>.

Common situations: Using shared-type entities (Dictionary-based join tables) and attempting to create a proxy through the Type-based overload instead of the name-based DbSet.Set(string) overload; scaffolding/migration code that iterates types generically.

Related errors


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