dotnet/efcore · error · InvalidOperationException

Cannot translate the '{comparisonOperator}' on an expression

Error message

Cannot translate the '{comparisonOperator}' on an expression of entity type '{entityType}' because it is a keyless entity. Consider using entity properties instead. For more information on keyless entity types, see https://go.microsoft.com/fwlink/?linkid=2141943.

What it means

Thrown from TryRewriteContainsEntity when an item passed to Queryable.Contains references an entity type that has no primary key (keyless). Without a key the translator cannot reduce entity equality to a key comparison, so it rejects the Contains.

Source

Thrown at src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs:1268

        return expression is MethodCallExpression { Method.IsGenericMethod: true } readValueMethodCall
            && readValueMethodCall.Method.GetGenericMethodDefinition() == ExpressionExtensions.ValueBufferTryReadValueMethod
                ? readValueMethodCall.Arguments[2].GetConstantValue<IProperty>()
                : null;
    }

    private bool TryRewriteContainsEntity(Expression? source, Expression item, [NotNullWhen(true)] out Expression? result)
    {
        result = null;

        if (item is not StructuralTypeReferenceExpression { StructuralType: IEntityType entityType })
        {
            return false;
        }

        var primaryKeyProperties = entityType.FindPrimaryKey()?.Properties;
        if (primaryKeyProperties == null)
        {
            throw new InvalidOperationException(
                CoreStrings.EntityEqualityOnKeylessEntityNotSupported(
                    nameof(Queryable.Contains), entityType.DisplayName()));
        }

        if (primaryKeyProperties.Count > 1)
        {
            throw new InvalidOperationException(
                CoreStrings.EntityEqualityOnCompositeKeyEntitySubqueryNotSupported(
                    nameof(Queryable.Contains), entityType.DisplayName()));
        }

        var property = primaryKeyProperties[0];
        Expression rewrittenSource;
        switch (source)
        {
            case ConstantExpression constantExpression:
                var values = constantExpression.GetConstantValue<IEnumerable>();
                var propertyValueList =

View on GitHub (pinned to 3a2006ef56)

Solutions

  1. Configure a primary key on the entity (HasKey(...) or by convention) if the underlying rows are uniquely identifiable.
  2. Rewrite the Contains to compare a primitive key property instead of the whole entity: db.Items.Select(i => i.Id).Contains(id).
  3. If the type is genuinely keyless, perform the membership check client-side via AsEnumerable().
  4. Re-evaluate whether the type should be keyless — most entities need a key.

Example fix

// before
db.Views.Contains(viewEntity);
// after - compare by a property
db.Views.Select(v => v.Code).Contains(viewEntity.Code);
Defensive patterns

Strategy: validation

Validate before calling

var et = dbContext.Model.FindEntityType(typeof(MyView));
if (et?.FindPrimaryKey() is null)
    throw new InvalidOperationException("Cannot use Contains on keyless MyView; compare a property");

Type guard

static bool IsKeyless(IEntityType et) => et.FindPrimaryKey() is null;

Try / catch

try { return db.Views.Contains(item); }
catch (InvalidOperationException ex) when (ex.Message.Contains("keyless entity"))
{
    return db.Views.AsEnumerable().Contains(item);
}

Prevention

When it happens

Trigger: A query like db.MyView.Contains(entity) where MyView is configured HasNoKey() and the item is a StructuralTypeReferenceExpression whose StructuralType is a keyless IEntityType.

Common situations: Using Contains/ equality against a keyless entity (a view, a raw SQL result, or a query result without keys). Forgetting to define a primary key on an entity mapped to a database view.

Related errors


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