@@ -403,19 +403,20 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string
403
403
bool joinIsNeeded ;
404
404
405
405
// For nullable entity comparisons we always need to add join (like not constrained one-to-one or not-found ignore associations).
406
- // For property-ref associations, we also need this unless finding a way in the IdentNode for the other hand of the comparison
407
- // to detect it should yield the property-ref columns instead of the primary key columns.
408
- bool comparisonWithNullableEntityOrThroughPropertyRef = Walker . IsComparativeExpressionClause
409
- && ( entityType . IsNullable || entityType . IsUniqueKeyReference ) ;
406
+ var comparisonWithNullableEntity = Walker . IsComparativeExpressionClause && entityType . IsNullable ;
407
+ // For property-ref association comparison, we also need to join unless finding a way in the node for the other hand of the comparison
408
+ // to detect it should yield the property-ref columns instead of the primary key columns. And if the other hand is an association too,
409
+ // it may be a reference to the primary key, so we would need to join anyway.
410
+ var comparisonThroughPropertyRef = Walker . IsComparativeExpressionClause && ! entityType . IsReferenceToPrimaryKey ;
410
411
411
- if ( IsDotNode ( parent ) )
412
+ if ( IsDotNode ( parent ) )
412
413
{
413
414
// our parent is another dot node, meaning we are being further dereferenced.
414
415
// thus we need to generate a join unless the parent refers to the associated
415
416
// entity's PK (because 'our' table would know the FK).
416
417
parentAsDotNode = ( DotNode ) parent ;
417
418
property = parentAsDotNode . _propertyName ;
418
- joinIsNeeded = generateJoin && ( ( Walker . IsSelectStatement && comparisonWithNullableEntityOrThroughPropertyRef ) || ! IsReferenceToPrimaryKey ( parentAsDotNode . _propertyName , entityType ) ) ;
419
+ joinIsNeeded = generateJoin && ( ( Walker . IsSelectStatement && comparisonWithNullableEntity ) || ! IsReferenceToPrimaryKey ( parentAsDotNode . _propertyName , entityType ) ) ;
419
420
}
420
421
else if ( ! Walker . IsSelectStatement )
421
422
{
@@ -429,14 +430,15 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string
429
430
else
430
431
{
431
432
joinIsNeeded = generateJoin || ( Walker . IsInSelect && ! Walker . IsInCase ) || ( Walker . IsInFrom && ! Walker . IsComparativeExpressionClause )
432
- || comparisonWithNullableEntityOrThroughPropertyRef ;
433
+ || comparisonWithNullableEntity || comparisonThroughPropertyRef ;
433
434
}
434
435
435
436
if ( joinIsNeeded )
436
437
{
437
- var forceLeftJoin = comparisonWithNullableEntityOrThroughPropertyRef && ! IsCorrelatedSubselect ;
438
+ // Subselect queries use theta style joins, which cannot be forced to left outer joins.
439
+ var forceLeftJoin = comparisonWithNullableEntity && ! IsCorrelatedSubselect ;
438
440
DereferenceEntityJoin ( classAlias , entityType , implicitJoin , parent , forceLeftJoin ) ;
439
- if ( comparisonWithNullableEntityOrThroughPropertyRef )
441
+ if ( comparisonWithNullableEntity || comparisonThroughPropertyRef )
440
442
{
441
443
_columns = FromElement . GetIdentityColumns ( ) ;
442
444
}
0 commit comments