Пример #1
0
            protected override Expression VisitExtension(Expression extensionExpression)
            {
                if (extensionExpression is ProjectionBindingExpression projectionBindingExpression)
                {
                    var projectionIndex = (int)GetProjectionIndex(projectionBindingExpression);
                    var projection      = _selectExpression.Projection[projectionIndex];

                    return(CreateGetStoreValueExpression(
                               _jObjectParameter,
                               projection.Alias,
                               ((SqlExpression)projection.Expression).TypeMapping,
                               projectionBindingExpression.Type));
                }

                if (extensionExpression is EntityShaperExpression shaperExpression)
                {
                    _currentEntityIndex++;

                    var jObjectVariable = Expression.Variable(typeof(JObject),
                                                              "jObject" + _currentEntityIndex);
                    var variables = new List <ParameterExpression> {
                        jObjectVariable
                    };

                    var expressions = new List <Expression>();

                    if (shaperExpression.ParentNavigation == null)
                    {
                        var projectionIndex = (int)GetProjectionIndex((ProjectionBindingExpression)shaperExpression.ValueBufferExpression);
                        var projection      = _selectExpression.Projection[projectionIndex];

                        expressions.Add(
                            Expression.Assign(
                                jObjectVariable,
                                Expression.TypeAs(
                                    CreateReadJTokenExpression(_jObjectParameter, projection.Alias),
                                    typeof(JObject))));

                        shaperExpression = shaperExpression.Update(
                            shaperExpression.ValueBufferExpression,
                            GetNestedShapers(shaperExpression.EntityType, shaperExpression.ValueBufferExpression));
                    }
                    else
                    {
                        var methodCallExpression = (MethodCallExpression)shaperExpression.ValueBufferExpression;
                        Debug.Assert(methodCallExpression.Method.IsGenericMethod &&
                                     methodCallExpression.Method.GetGenericMethodDefinition() == EntityMaterializerSource.TryReadValueMethod);

                        var navigation = (INavigation)((ConstantExpression)methodCallExpression.Arguments[2]).Value;

                        expressions.Add(
                            Expression.Assign(
                                jObjectVariable,
                                Expression.TypeAs(
                                    CreateReadJTokenExpression(_jObjectParameter, navigation.GetTargetType().GetCosmosContainingPropertyName()),
                                    typeof(JObject))));
                    }

                    var parentJObject = _jObjectParameter;
                    _jObjectParameter = jObjectVariable;
                    expressions.Add(Expression.Condition(
                                        Expression.Equal(jObjectVariable, Expression.Constant(null, jObjectVariable.Type)),
                                        Expression.Constant(null, shaperExpression.Type),
                                        Visit(_shapedQueryCompilingExpressionVisitor.InjectEntityMaterializer(shaperExpression))));
                    _jObjectParameter = parentJObject;

                    return(Expression.Block(
                               shaperExpression.Type,
                               variables,
                               expressions));
                }

                if (extensionExpression is CollectionShaperExpression collectionShaperExpression)
                {
                    throw new NotImplementedException();
                }

                return(base.VisitExtension(extensionExpression));
            }
            protected override Expression VisitExtension(Expression extensionExpression)
            {
                switch (extensionExpression)
                {
                case ProjectionBindingExpression projectionBindingExpression:
                {
                    if (_currentEmbeddedNavigationInfo != null)
                    {
                        return(extensionExpression);
                    }

                    var projectionIndex = (int)GetProjectionIndex(projectionBindingExpression);
                    var projection      = _selectExpression.Projection[projectionIndex];

                    return(CreateGetStoreValueExpression(
                               _jObjectParameter,
                               projection.Alias,
                               ((SqlExpression)projection.Expression).TypeMapping,
                               projectionBindingExpression.Type));
                }

                case EntityShaperExpression shaperExpression:
                {
                    _currentEntityIndex++;

                    var jObjectVariable = Expression.Variable(typeof(JObject),
                                                              "jObject" + _currentEntityIndex);
                    var variables = new List <ParameterExpression> {
                        jObjectVariable
                    };

                    var expressions           = new List <Expression>();
                    var valueBufferExpression = shaperExpression.ValueBufferExpression;
                    if (_currentEmbeddedNavigationInfo?.Navigation == null)
                    {
                        var projectionIndex = (int)GetProjectionIndex((ProjectionBindingExpression)valueBufferExpression);
                        var projection      = _selectExpression.Projection[projectionIndex];

                        expressions.Add(
                            Expression.Assign(
                                jObjectVariable,
                                Expression.TypeAs(
                                    CreateReadJTokenExpression(_jObjectParameter, projection.Alias),
                                    typeof(JObject))));
                    }
                    else
                    {
                        expressions.Add(
                            Expression.Assign(
                                jObjectVariable,
                                Expression.TypeAs(
                                    CreateReadJTokenExpression(
                                        _jObjectParameter,
                                        _currentEmbeddedNavigationInfo.Navigation.GetTargetType().GetCosmosContainingPropertyName()),
                                    typeof(JObject))));
                    }

                    var parentJObject = _jObjectParameter;
                    _jObjectParameter = jObjectVariable;

                    var materializerExpression = Visit(_shapedQueryCompilingExpressionVisitor.InjectEntityMaterializer(shaperExpression));
                    materializerExpression = InjectEmbeddedMaterializers(materializerExpression, valueBufferExpression);

                    _jObjectParameter = parentJObject;

                    expressions.Add(Expression.Condition(
                                        Expression.Equal(jObjectVariable, Expression.Constant(null, jObjectVariable.Type)),
                                        Expression.Constant(null, shaperExpression.Type),
                                        materializerExpression));

                    return(Expression.Block(
                               shaperExpression.Type,
                               variables,
                               expressions));
                }

                case IncludeExpression includeExpression:
                    var fk = includeExpression.Navigation.ForeignKey;
                    if (includeExpression.Navigation.IsDependentToPrincipal() ||
                        fk.DeclaringEntityType.IsDocumentRoot())
                    {
                        throw new InvalidOperationException("Non-embedded IncludeExpression " + new ExpressionPrinter().Print(includeExpression));
                    }

                    var parentNavigation = _currentEmbeddedNavigationInfo ?? new EmbeddedNavigationInfo();
                    _currentEmbeddedNavigationInfo = new EmbeddedNavigationInfo(includeExpression.Navigation);

                    Visit(includeExpression.NavigationExpression);

                    parentNavigation.EmbeddedNavigations.Add(_currentEmbeddedNavigationInfo);
                    _currentEmbeddedNavigationInfo = parentNavigation;

                    return(Visit(includeExpression.EntityExpression));
                }

                return(base.VisitExtension(extensionExpression));
            }