dotnet/efcore · error · InvalidOperationException
Cannot translate the
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
When translating Queryable.Contains on an entity, StructuralEquality needs the entity's single primary key property to build an IN clause. If FindPrimaryKey returns null (keyless entity) it throws InvalidOperationException CoreStrings.EntityEqualityOnKeylessEntityNotSupported — Contains cannot be expressed without a key.
Solutions
- Compare on a concrete property instead of the entity: .Where(x => ids.Contains(x.SomeId)).
- Configure a key on the entity if equality semantics are genuinely needed.
- Materialize the keyless sequence client-side and filter there.
Example fix
// before var q = db.Views.Where(v => allowed.Contains(v)); // after var q = db.Views.Where(v => allowedIds.Contains(v.Code));
Defensive patterns
Strategy: validation
Validate before calling
// compare on scalar keys, not on the entity
static IQueryable<T> InByKey<T>(IQueryable<T> q, IEnumerable<string> keys, string propName)
where T : class
=> q.Where(x => keys.Contains(EF.Property<string>(x, propName))); Type guard
static bool EntityHasKey<T>(DbContext ctx)
=> ctx.Model.FindEntityType(typeof(T))?.FindPrimaryKey() is not null; Prevention
- Avoid Contains on entity instances; project to a key first.
- Add a key to any entity used in equality filters.
- Test Contains behavior whenever a key is removed.
When it happens
Trigger: Calling .Contains(entity) or building an IN-style filter where the element type is a keyless entity (HasNoKey configured).
Common situations: Modeling a view/report type as keyless and then attempting Contains/Any-equality filters against it, or accidentally removing a key configuration.
Related errors
- Cannot translate ' ' on a subquery expression of entity…
- A FromSqlExpression has an invalid arguments expression type
- Bind property on structural type coming out of scalar…
- Complex projections in subqueries are currently unsupported.
- Cosmos SQL does not allow Offset without Limit. Consider…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/02aef052e7244e5a.
Report an issue: GitHub.
Appendix: 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 3a2006ef56)