示例#1
0
            protected override Expression VisitExtension(Expression extensionExpression)
            {
                switch (extensionExpression)
                {
                case EntityShaperExpression entityShaperExpression:
                {
                    var key = GenerateKey((ProjectionBindingExpression)entityShaperExpression.ValueBufferExpression);
                    if (!_mapping.TryGetValue(key, out var accessor))
                    {
                        var entityParameter = Expression.Parameter(entityShaperExpression.Type);
                        _variables.Add(entityParameter);
                        _expressions.Add(Expression.Assign(entityParameter, entityShaperExpression));

                        if (_containsCollectionMaterialization)
                        {
                            _valuesArrayInitializers.Add(entityParameter);
                            accessor = Expression.Convert(
                                Expression.ArrayIndex(
                                    _valuesArrayExpression,
                                    Expression.Constant(_valuesArrayInitializers.Count - 1)),
                                entityShaperExpression.Type);
                        }
                        else
                        {
                            accessor = entityParameter;
                        }

                        _mapping[key] = accessor;
                    }

                    return(accessor);
                }

                case ProjectionBindingExpression projectionBindingExpression:
                {
                    var key = GenerateKey(projectionBindingExpression);
                    if (!_mapping.TryGetValue(key, out var accessor))
                    {
                        var valueParameter = Expression.Parameter(projectionBindingExpression.Type);
                        _variables.Add(valueParameter);
                        _expressions.Add(Expression.Assign(valueParameter, projectionBindingExpression));

                        if (_containsCollectionMaterialization)
                        {
                            var expressionToAdd = (Expression)valueParameter;
                            if (expressionToAdd.Type.IsValueType)
                            {
                                expressionToAdd = Expression.Convert(expressionToAdd, typeof(object));
                            }

                            _valuesArrayInitializers.Add(expressionToAdd);
                            accessor = Expression.Convert(
                                Expression.ArrayIndex(
                                    _valuesArrayExpression,
                                    Expression.Constant(_valuesArrayInitializers.Count - 1)),
                                projectionBindingExpression.Type);
                        }
                        else
                        {
                            accessor = valueParameter;
                        }

                        _mapping[key] = accessor;
                    }

                    return(accessor);
                }

                case IncludeExpression includeExpression:
                {
                    var entity = Visit(includeExpression.EntityExpression);
                    if (includeExpression.NavigationExpression is RelationalCollectionShaperExpression
                        relationalCollectionShaperExpression)
                    {
                        var innerShaper = new ShaperExpressionProcessingExpressionVisitor(
                            _selectExpression, _dataReaderParameter, _resultCoordinatorParameter, null)
                                          .Inject(relationalCollectionShaperExpression.InnerShaper);

                        _collectionPopulatingExpressions.Add(new CollectionPopulatingExpression(
                                                                 relationalCollectionShaperExpression.Update(
                                                                     relationalCollectionShaperExpression.ParentIdentifier,
                                                                     relationalCollectionShaperExpression.OuterIdentifier,
                                                                     relationalCollectionShaperExpression.SelfIdentifier,
                                                                     innerShaper),
                                                                 includeExpression.Navigation.ClrType,
                                                                 true));

                        _includeExpressions.Add(new CollectionInitializingExpression(
                                                    relationalCollectionShaperExpression.CollectionId,
                                                    entity,
                                                    relationalCollectionShaperExpression.ParentIdentifier,
                                                    relationalCollectionShaperExpression.OuterIdentifier,
                                                    includeExpression.Navigation,
                                                    includeExpression.Navigation.ClrType));
                    }
                    else
                    {
                        _includeExpressions.Add(includeExpression.Update(
                                                    entity,
                                                    Visit(includeExpression.NavigationExpression)));
                    }

                    return(entity);
                }

                case RelationalCollectionShaperExpression relationalCollectionShaperExpression2:
                {
                    var key = GenerateKey(relationalCollectionShaperExpression2);
                    if (!_mapping.TryGetValue(key, out var accessor))
                    {
                        var innerShaper = new ShaperExpressionProcessingExpressionVisitor(
                            _selectExpression, _dataReaderParameter, _resultCoordinatorParameter, null)
                                          .Inject(relationalCollectionShaperExpression2.InnerShaper);

                        _collectionPopulatingExpressions.Add(new CollectionPopulatingExpression(
                                                                 relationalCollectionShaperExpression2.Update(
                                                                     relationalCollectionShaperExpression2.ParentIdentifier,
                                                                     relationalCollectionShaperExpression2.OuterIdentifier,
                                                                     relationalCollectionShaperExpression2.SelfIdentifier,
                                                                     innerShaper),
                                                                 relationalCollectionShaperExpression2.Type,
                                                                 false));

                        var collectionParameter = Expression.Parameter(relationalCollectionShaperExpression2.Type);
                        _variables.Add(collectionParameter);
                        _expressions.Add(Expression.Assign(
                                             collectionParameter,
                                             new CollectionInitializingExpression(
                                                 relationalCollectionShaperExpression2.CollectionId,
                                                 null,
                                                 relationalCollectionShaperExpression2.ParentIdentifier,
                                                 relationalCollectionShaperExpression2.OuterIdentifier,
                                                 relationalCollectionShaperExpression2.Navigation,
                                                 relationalCollectionShaperExpression2.Type)));

                        _valuesArrayInitializers.Add(collectionParameter);
                        accessor = Expression.Convert(
                            Expression.ArrayIndex(
                                _valuesArrayExpression,
                                Expression.Constant(_valuesArrayInitializers.Count - 1)),
                            relationalCollectionShaperExpression2.Type);

                        _mapping[key] = accessor;
                    }

                    return(accessor);
                }
                }

                return(base.VisitExtension(extensionExpression));
            }