예제 #1
0
            private Expression MaterializeObject(Expression visited)
            {
                if (depth > 0 && !extraProperties)
                {
                    return(SqlServerJsonValueReader.CreateReadComplexPropertyExpression(
                               visited.Type,
                               jsonTextReader,
                               GetNameParts().LastOrDefault(),
                               Expression.Lambda(
                                   visited,
                                   GetMaterializerName(),
                                   Array.Empty <ParameterExpression>())));
                }

                return(visited);
            }
예제 #2
0
            protected override Expression VisitLeaf(Expression node)
            {
                if (node.Type.IsScalarType())
                {
                    var sqlColumnExpression = node as SqlColumnExpression;
                    var typeMapping         = sqlColumnExpression?.TypeMapping ?? typeMappingProvider.FindMapping(node.Type);

                    if (typeMapping?.TargetConversion is null)
                    {
                        return(SqlServerJsonValueReader.CreateReadScalarExpression(
                                   node.Type,
                                   jsonTextReader,
                                   GetNameParts().Last()));
                    }

                    var result
                        = SqlServerJsonValueReader.CreateReadScalarExpression(
                              typeMapping.SourceType,
                              jsonTextReader,
                              GetNameParts().Last());

                    var mappingParameter = typeMapping.TargetConversion.Parameters.Single();

                    result
                        = Expression.Block(
                              variables: new[] { mappingParameter },
                              expressions: new Expression[]
                    {
                        Expression.Assign(mappingParameter, result),
                        Expression.Convert(typeMapping.TargetConversion.Body, node.Type),
                    });

                    return(result);
                }
                else if (node.Type.IsSequenceType())
                {
                    var sequenceType = node.Type.GetSequenceType();
                    var extracted    = ExtractProjectionExpression(node);

                    Expression materializer;

                    if (sequenceType.IsScalarType())
                    {
                        // TODO: Get rid of the need to put this constant multiple places.
                        var name = "$c";

                        switch (extracted)
                        {
                        case SqlColumnExpression sqlColumnExpression:
                        {
                            name = sqlColumnExpression.ColumnName;
                            break;
                        }

                        case SqlAliasExpression sqlAliasExpression:
                        {
                            name = sqlAliasExpression.Alias;
                            break;
                        }
                        }

                        materializer = SqlServerJsonValueReader.CreateReadScalarExpression(sequenceType, jsonTextReader, name);
                    }
                    else
                    {
                        if (extracted == node)
                        {
                            return(SqlServerJsonValueReader.CreateReadOpaqueObjectExpression(node.Type, jsonTextReader));
                        }

                        var visitor = new ComplexTypeMaterializerBuildingExpressionVisitor(jsonTextReader, typeMappingProvider);

                        materializer = visitor.Visit(extracted);
                    }

                    return(CreateSequenceExpression(
                               SqlServerJsonValueReader.CreateReadArrayExpression(
                                   sequenceType,
                                   jsonTextReader,
                                   GetNameParts().LastOrDefault(),
                                   Expression.Lambda(
                                       materializer,
                                       GetMaterializerName(),
                                       Array.Empty <ParameterExpression>())),
                               node.Type));
                }
                else
                {
                    var extracted = ExtractProjectionExpression(node);

                    if (extracted == node)
                    {
                        return(SqlServerJsonValueReader.CreateReadOpaqueObjectExpression(node.Type, jsonTextReader));
                    }

                    var visitor = new ComplexTypeMaterializerBuildingExpressionVisitor(jsonTextReader, typeMappingProvider);
                    var result  = visitor.Visit(extracted);

                    if (result is MethodCallExpression call &&
                        call.Method.DeclaringType == typeof(SqlServerJsonValueReader))
                    {
                        return(result);
                    }

                    return(SqlServerJsonValueReader.CreateReadComplexObjectExpression(
                               node.Type,
                               jsonTextReader,
                               Expression.Lambda(
                                   result,
                                   GetMaterializerName(),
                                   Array.Empty <ParameterExpression>())));
                }
            }