Bug description
A query that projects an object conditionally using child != null && grandChild != null ? ... : null executes successfully on its own, but fails to translate once a Where clause references a property of the projected object.
The equivalent logic expressed using nested ternary operators (child != null ? grandChild != null ? ... : null : null) translates successfully, even though it is semantically equivalent.
This suggests that EF Core generates a different expression tree for the two forms and does not correctly translate the && version when the projection is later referenced in a predicate.
Expected behavior
Both forms are semantically equivalent and should either translate successfully or fail consistently. The query using the && conditional should translate the same way as the nested ternary version.
Actual behavior
The query fails during translation with:
System.InvalidOperationException: The LINQ expression ... could not be translated.
Additional information
- The initial projection (
ToListAsync()) succeeds.
- Translation only fails when a subsequent query operator references the projected conditional object.
- Rewriting the condition as nested ternary operators is a viable workaround, indicating this is likely a query translation issue rather than an unsupported LINQ pattern.
Your code
// Entities
public class Parent
{
public Guid Id { get; set; }
public Guid? ChildId { get; set; }
}
public class Child
{
public Guid Id { get; set; }
public Guid? GrandChildId { get; set; }
}
public class GrandChild
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
}
// Reproduce the bug
var query = from parent in context.Parents
join child in context.Children on parent.ChildId equals child.Id into childGroup
from child in childGroup.DefaultIfEmpty()
join grandChild in context.GrandChildren on child.GrandChildId equals grandChild.Id into grandChildGroup
from grandChild in grandChildGroup.DefaultIfEmpty()
select new
{
Id = parent.Id,
Child = child != null && grandChild != null ? new
{
GrandChildId = child.GrandChildId
} : null,
};
// ✅ This works
var result = await query.ToListAsync();
// ❌ This throws InvalidOperationException - cannot be translated
var result2 = await query.Where(x => x.Child.GrandChildId != null).ToListAsync();
// Workaround - Nested ternary operators
var workingQuery = from parent in context.Parents
join child in context.Children on parent.ChildId equals child.Id into childGroup
from child in childGroup.DefaultIfEmpty()
join grandChild in context.GrandChildren on child.GrandChildId equals grandChild.Id into grandChildGroup
from grandChild in grandChildGroup.DefaultIfEmpty()
select new
{
Id = parent.Id,
// Workaround: nest the ternary operators
Child = child != null ? grandChild != null ? new
{
GrandChildId = child.GrandChildId
} : null : null,
};
// ✅ Workaround using nested ternary operator works
var workingResult = await workingQuery.ToListAsync();
Stack traces
System.InvalidOperationException: The LINQ expression 'DbSet<Parent>()
.LeftJoin(
inner: DbSet<Child>(),
outerKeySelector: p => (object)p.ChildId,
innerKeySelector: c => (object)(Guid?)c.Id,
resultSelector: (p, c) => new TransparentIdentifier<Parent, Child>(
Outer = p,
Inner = c
))
.LeftJoin(
inner: DbSet<GrandChild>(),
outerKeySelector: ti => (object)ti.Inner.GrandChildId,
innerKeySelector: g => (object)(Guid?)g.Id,
resultSelector: (ti, g) => new TransparentIdentifier<TransparentIdentifier<Parent, Child>, GrandChild>(
Outer = ti,
Inner = g
))
.Where(ti0 => ti0.Outer.Inner != null && ti0.Inner != null ? new Child{ GrandChildId = ti0.Outer.Inner.GrandChildId }
: null.GrandChildId != null)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorExpression[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass11_0`1.<ExecuteCore>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
``
Verbose output
EF Core version
10.0.9
Database provider
Microsoft.EntityFrameworkCore.SqlServer
Target framework
.NET 10
Operating system
Windows 11
IDE
Visual Studio 2026 18.7.3
Bug description
A query that projects an object conditionally using
child != null && grandChild != null ? ... : nullexecutes successfully on its own, but fails to translate once aWhereclause references a property of the projected object.The equivalent logic expressed using nested ternary operators (
child != null ? grandChild != null ? ... : null : null) translates successfully, even though it is semantically equivalent.This suggests that EF Core generates a different expression tree for the two forms and does not correctly translate the
&&version when the projection is later referenced in a predicate.Expected behavior
Both forms are semantically equivalent and should either translate successfully or fail consistently. The query using the
&&conditional should translate the same way as the nested ternary version.Actual behavior
The query fails during translation with:
Additional information
ToListAsync()) succeeds.Your code
Stack traces
Verbose output
EF Core version
10.0.9
Database provider
Microsoft.EntityFrameworkCore.SqlServer
Target framework
.NET 10
Operating system
Windows 11
IDE
Visual Studio 2026 18.7.3