private (NavigationExpansionExpression navigationExpression, Expression nullKeyExpression) CreateNullComparisonArguments( NavigationBindingExpression navigationBindingExpression, NavigationExpansionExpression navigationExpansionExpression) { var navigationKeyAccessExpression = NavigationExpansionHelpers.CreateKeyAccessExpression( navigationBindingExpression, new[] { navigationBindingExpression.EntityType.FindPrimaryKey().Properties.First() }, addNullCheck: true); var nullKeyExpression = NavigationExpansionHelpers.CreateNullKeyExpression( navigationKeyAccessExpression.Type, keyCount: 1); var newNavigationExpansionExpressionState = new NavigationExpansionExpressionState( navigationExpansionExpression.State.CurrentParameter, navigationExpansionExpression.State.SourceMappings, Expression.Lambda(navigationKeyAccessExpression, navigationExpansionExpression.State.PendingSelector.Parameters[0]), applyPendingSelector: true, navigationExpansionExpression.State.PendingOrderings, navigationExpansionExpression.State.PendingIncludeChain, // we need to remap cardinality reducing operator since it's source type has now changed navigationExpansionExpression.State.PendingCardinalityReducingOperator?.GetGenericMethodDefinition().MakeGenericMethod(navigationKeyAccessExpression.Type), navigationExpansionExpression.State.CustomRootMappings, navigationExpansionExpression.State.MaterializeCollectionNavigation); var navigationExpression = new NavigationExpansionExpression( navigationExpansionExpression.Operand, newNavigationExpansionExpressionState, navigationKeyAccessExpression.Type); return(navigationExpression, nullKeyExpression); }
private Expression TryRewriteNavigationComparison(Expression left, Expression right, bool equality) { var leftBinding = left as NavigationBindingExpression; var rightBinding = right as NavigationBindingExpression; var leftNullConstant = left.IsNullConstantExpression(); var rightNullConstant = right.IsNullConstantExpression(); Expression newLeft = null; Expression newRight = null; // comparing two different collection navigations always returns false if (leftBinding != null && rightBinding != null && leftBinding.NavigationTreeNode.Navigation != rightBinding.NavigationTreeNode.Navigation && (leftBinding.NavigationTreeNode.IsCollection || rightBinding.NavigationTreeNode.IsCollection)) { if (leftBinding.NavigationTreeNode.IsCollection) { var parentTreeNode = leftBinding.NavigationTreeNode.Parent; parentTreeNode.Children.Remove(leftBinding.NavigationTreeNode); } if (rightBinding.NavigationTreeNode.IsCollection) { var parentTreeNode = rightBinding.NavigationTreeNode.Parent; parentTreeNode.Children.Remove(rightBinding.NavigationTreeNode); } return(Expression.Constant(false)); } if (leftBinding != null && rightBinding != null && leftBinding.EntityType == rightBinding.EntityType) { if (leftBinding.NavigationTreeNode.Navigation == rightBinding.NavigationTreeNode.Navigation && leftBinding.NavigationTreeNode.IsCollection) { leftBinding = CreateParentBindingExpression(leftBinding); rightBinding = CreateParentBindingExpression(rightBinding); } // TODO: what about entities without PKs? var primaryKeyProperties = leftBinding.EntityType.FindPrimaryKey().Properties; newLeft = NavigationExpansionHelpers.CreateKeyAccessExpression(leftBinding, primaryKeyProperties, addNullCheck: leftBinding.NavigationTreeNode.Optional); newRight = NavigationExpansionHelpers.CreateKeyAccessExpression(rightBinding, primaryKeyProperties, addNullCheck: rightBinding.NavigationTreeNode.Optional); } if (leftBinding != null && rightNullConstant) { if (leftBinding.NavigationTreeNode.IsCollection) { leftBinding = CreateParentBindingExpression(leftBinding); } // TODO: what about entities without PKs? var primaryKeyProperties = leftBinding.EntityType.FindPrimaryKey().Properties; newLeft = NavigationExpansionHelpers.CreateKeyAccessExpression(leftBinding, primaryKeyProperties, addNullCheck: leftBinding.NavigationTreeNode.Optional); newRight = NavigationExpansionHelpers.CreateNullKeyExpression(newLeft.Type, primaryKeyProperties.Count); } if (rightBinding != null && leftNullConstant) { if (rightBinding.NavigationTreeNode.IsCollection) { rightBinding = CreateParentBindingExpression(rightBinding); } // TODO: what about entities without PKs? var primaryKeyProperties = rightBinding.EntityType.FindPrimaryKey().Properties; newRight = NavigationExpansionHelpers.CreateKeyAccessExpression(rightBinding, primaryKeyProperties, addNullCheck: rightBinding.NavigationTreeNode.Optional); newLeft = NavigationExpansionHelpers.CreateNullKeyExpression(newRight.Type, primaryKeyProperties.Count); } if (newLeft == null || newRight == null) { return(null); } if (newLeft.Type != newRight.Type) { if (newLeft.Type.IsNullableType()) { newRight = Expression.Convert(newRight, newLeft.Type); } else { newLeft = Expression.Convert(newLeft, newRight.Type); } } return(equality ? Expression.Equal(newLeft, newRight) : Expression.NotEqual(newLeft, newRight)); }