dotnet/efcore · error · NotImplementedException

DbSet local symbol

Error message

DbSet local symbol

What it means

After binding an identifier to a local/field/property symbol, `VisitIdentifierName` checks `if (typeSymbol.Name.Contains("DbSet"))` and throws `NotImplementedException("DbSet local symbol")`. Referencing a `DbSet<T>` as a captured local variable or field inside a query is not supported — query roots must go through the `DbContext` itself.

Source

Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:430

            case ILocalSymbol s:
                typeSymbol = s.Type;
                break;
            case IFieldSymbol s:
                typeSymbol = s.Type;
                break;
            case IPropertySymbol s:
                typeSymbol = s.Type;
                break;
            case null:
                throw new InvalidOperationException($"Identifier without symbol: {identifierName}");
            default:
                throw new UnreachableException($"IdentifierName of type {symbol.GetType().Name}: {identifierName}");
        }

        // TODO: Separate out EF Core-specific logic (EF Core would extend this visitor)
        if (typeSymbol.Name.Contains("DbSet"))
        {
            throw new NotImplementedException("DbSet local symbol");
        }

        // We have an identifier which isn't in our parameters stack.

        // First, if the identifier type is the user's DbContext type (e.g. DbContext local variable, or field/property),
        // return a constant over that.
        if (typeSymbol.Equals(_userDbContextSymbol, SymbolEqualityComparer.Default))
        {
            return Constant(_userDbContext);
        }

        // The Translate entry point into the translator uses Roslyn's data flow analysis to locate all local variables flowing in
        // (e.g. captured variables), and populates the _dataFlowsIn dictionary with them (with null values).
        if (symbol is ILocalSymbol localSymbol && _dataFlowsIn.TryGetValue(localSymbol, out var memberExpression))
        {
            // The first time we see a flowing-in variable, we create MemberExpression for it and cache it in _dataFlowsIn.
            return memberExpression
                ?? (_dataFlowsIn[localSymbol] =

View on GitHub (pinned to dbf9771522)

Solutions

  1. Reference the `DbSet` directly off the `DbContext` inside the query (`ctx.Blogs.Where(...)`).
  2. Pass the `DbContext` (which the translator resolves as a constant) instead of a `DbSet` local.

Example fix

// before
var blogs = ctx.Blogs;
var q = blogs.Where(b => b.Title == "x");
// after
var q = ctx.Blogs.Where(b => b.Title == "x");
Defensive patterns

Strategy: validation

Validate before calling

// Reject captured DbSet locals/fields before translation.
var dbsetRefs = node.DescendantNodes().OfType<IdentifierNameSyntax>()
    .Where(id => semanticModel.GetSymbolInfo(id).Symbol is { } s
                 && s.Kind is SymbolKind.Local or SymbolKind.Field or SymbolKind.Property
                 && (semanticModel.GetTypeInfo(id).Type?.Name.Contains("DbSet") ?? false))
    .ToList();
if (dbsetRefs.Count != 0)
    throw new NotSupportedException(
        "Captured DbSet locals/fields are unsupported; reference the DbSet directly off the DbContext.");

translator.Translate(node, semanticModel);

Try / catch

try { translator.Translate(node, semanticModel); }
catch (NotImplementedException ex) when (ex.Message == "DbSet local symbol")
{ /* rewrite the query to access ctx.Blogs directly */ }

Prevention

When it happens

Trigger: A precompiled query that captures a `DbSet<T>` into a local/field and then queries it, e.g. `var set = ctx.Blogs; ... set.Where(b => ...)` inside the translated lambda.

Common situations: Refactoring a query to reuse a `DbSet` variable, or helper methods that take/return `DbSet` locals used within translated expressions.

Related errors


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