コード例 #1
0
        public SqlExpression TranslateArrayLength(SqlExpression expression)
        {
            if (expression is ColumnExpression columnExpression &&
                columnExpression.TypeMapping is NpgsqlJsonTypeMapping mapping)
            {
                return(_sqlExpressionFactory.Function(
                           mapping.IsJsonb ? "jsonb_array_length" : "json_array_length",
                           new[] { expression }, typeof(int)));
            }

            if (expression is JsonTraversalExpression traversal)
            {
                // The traversal expression has ReturnsText=true (e.g. ->> not ->), so we recreate it to return
                // the JSON object instead.
                var lastPathComponent = traversal.Path.Last();
                var newTraversal      = new JsonTraversalExpression(
                    traversal.Expression, traversal.Path,
                    returnsText: false,
                    lastPathComponent.Type,
                    _sqlExpressionFactory.FindMapping(lastPathComponent.Type));

                var jsonMapping = (NpgsqlJsonTypeMapping)traversal.Expression.TypeMapping;
                return(_sqlExpressionFactory.Function(
                           jsonMapping.IsJsonb ? "jsonb_array_length" : "json_array_length",
                           new[] { newTraversal }, typeof(int)));
            }

            return(null);
        }
コード例 #2
0
        public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            if (method.DeclaringType != typeof(JsonElement) ||
                !(instance.TypeMapping is NpgsqlJsonTypeMapping mapping))
            {
                return(null);
            }

            if (method == GetProperty || method == ArrayIndexer)
            {
                // The first time we see a JSON traversal it's on a column - create a JsonTraversalExpression.
                // Traversals on top of that get appended into the same expression.
                return(instance is ColumnExpression columnExpression
                    ? _sqlExpressionFactory.JsonTraversal(columnExpression, arguments, false, typeof(string), mapping)
                    : instance is JsonTraversalExpression prevPathTraversal
                        ? prevPathTraversal.Append(_sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[0]))
                        : null);
            }

            if (GetMethods.Contains(method.Name) &&
                arguments.Count == 0 &&
                instance is JsonTraversalExpression traversal)
            {
                var traversalToText = new JsonTraversalExpression(
                    traversal.Expression,
                    traversal.Path,
                    returnsText: true,
                    typeof(string),
                    _stringTypeMapping);

                return(method.Name == nameof(JsonElement.GetString)
                    ? traversalToText
                    : ConvertFromText(traversalToText, method.ReturnType));
            }

            if (method == GetArrayLength)
            {
                return(_sqlExpressionFactory.Function(
                           mapping.IsJsonb ? "jsonb_array_length" : "json_array_length",
                           new[] { instance }, typeof(int)));
            }

            if (method.Name.StartsWith("TryGet") && arguments.Count == 0)
            {
                throw new InvalidOperationException($"The TryGet* methods on {nameof(JsonElement)} aren't translated yet, use Get* instead.'");
            }

            return(null);
        }