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 by TryRewriteContainsEntity when a Queryable.Contains call (or entity equality) targets a keyless entity type. Keyless entities have no primary key, so EF cannot rewrite an entity-based Contains/equality into a key comparison for Cosmos SQL. Contains on keyless entities is not translatable.
Source
Thrown at src/EFCore.Cosmos/Query/Internal/CosmosSqlTranslatingExpressionVisitor.StructuralEquality.cs:37
private static readonly MethodInfo ParameterListValueExtractorMethod =
typeof(CosmosSqlTranslatingExpressionVisitor).GetTypeInfo().GetDeclaredMethod(nameof(ParameterListValueExtractor))!;
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;
switch (primaryKeyProperties)
{
case null:
throw new InvalidOperationException(
CoreStrings.EntityEqualityOnKeylessEntityNotSupported(
nameof(Queryable.Contains), entityType.DisplayName()));
case { Count: > 1 }:
throw new InvalidOperationException(
CoreStrings.EntityEqualityOnCompositeKeyEntitySubqueryNotSupported(
nameof(Queryable.Contains), entityType.DisplayName()));
}
var property = primaryKeyProperties[0];
Expression rewrittenSource;
switch (source)
{
case SqlConstantExpression sqlConstantExpression:
var values = (IEnumerable)sqlConstantExpression.Value!;
var propertyValueList =
(IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(property.ClrType.MakeNullable()))!;
var propertyGetter = property.GetGetter();View on GitHub (pinned to dbf9771522)
Solutions
- Compare on a concrete property of the keyless entity instead of the entity instance: ids.Contains(v.SomeId).
- If the entity should be identifiable, define a key on it (remove HasNoKey) so entity equality can translate.
- Materialize to a set of scalar keys client-side and use Contains on those scalars.
Example fix
// before var view = context.Views.First(); var exists = context.Views.Contains(view); // after var viewId = context.Views.Select(v => v.Code).First(); var exists = context.Views.Any(v => v.Code == viewId);
Defensive patterns
Strategy: validation
Validate before calling
// Compare on scalar keys, not on keyless entity references var codes = views.Select(v => v.Code).ToArray(); var exists = context.Views.Any(v => codes.Contains(v.Code));
Type guard
static bool IsKeyless(IEntityType et) => et.FindPrimaryKey() is null;
Prevention
- Never use Contains/entity-equality on keyless entity instances.
- Compare scalar properties of keyless entities instead.
- Add a key if entity identity comparison is genuinely needed.
When it happens
Trigger: Calling .Contains(entity) or comparing entity instances where the entity type is configured HasNoKey(). For example: context.Views.Contains(view) where View is a keyless query root.
Common situations: Using keyless entity types (database views, raw SQL results, read-only projections) in Contains or entity-equality comparisons. Migrating a relational Contains pattern to Cosmos with a keyless type.
Related errors
- Cannot translate '{comparisonOperator}' on a subquery expres
- The '{methodName}' method is not supported because the query
- The LINQ expression '{expression}' could not be translated.
- A FromSqlExpression has an invalid arguments expression type
- The LINQ expression '{expression}' could not be translated.
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/02aef052e7244e5a.
Report an issue: GitHub.