コード例 #1
0
        private SqlExpression OptimizeCompareTo(
            SqlBinaryExpression sqlBinaryExpression,
            int intValue,
            CaseExpression caseExpression)
        {
            var testLeft     = ((SqlBinaryExpression)caseExpression.WhenClauses[0].Test).Left;
            var testRight    = ((SqlBinaryExpression)caseExpression.WhenClauses[0].Test).Right;
            var operatorType = sqlBinaryExpression.Right is SqlConstantExpression
                ? sqlBinaryExpression.OperatorType
                : sqlBinaryExpression.OperatorType switch
            {
                ExpressionType.GreaterThan => ExpressionType.LessThan,
                ExpressionType.GreaterThanOrEqual => ExpressionType.LessThanOrEqual,
                ExpressionType.LessThan => ExpressionType.GreaterThan,
                ExpressionType.LessThanOrEqual => ExpressionType.GreaterThanOrEqual,
                _ => sqlBinaryExpression.OperatorType
            };

            switch (operatorType)
            {
            // CompareTo(a, b) != 0 -> a != b
            // CompareTo(a, b) != 1 -> a <= b
            // CompareTo(a, b) != -1 -> a >= b
            case ExpressionType.NotEqual:
                return((SqlExpression)Visit(intValue switch
                {
                    0 => _sqlExpressionFactory.NotEqual(testLeft, testRight),
                    1 => _sqlExpressionFactory.LessThanOrEqual(testLeft, testRight),
                    _ => _sqlExpressionFactory.GreaterThanOrEqual(testLeft, testRight),
                }));
コード例 #2
0
        /// <summary>
        /// 更新 Select 语句
        /// </summary>
        /// <param name="selectExpression"></param>
        /// <returns></returns>
        private Expression VisitSelect(SelectExpression selectExpression)
        {
            var oldOffset = selectExpression.Offset;

            if (oldOffset == null)
            {
                return(selectExpression);
            }

            var oldLimit     = selectExpression.Limit;
            var oldOrderings = selectExpression.Orderings;

            // 在子查询中 OrderBy 必须写 Top 数量
            var newOrderings = oldOrderings.Count > 0 && (oldLimit != null || selectExpression == root)
                ? oldOrderings.ToList()
                : new List <OrderingExpression>();

            // 更新表达式
            selectExpression = selectExpression.Update(selectExpression.Projection.ToList(),
                                                       selectExpression.Tables.ToList(),
                                                       selectExpression.Predicate,
                                                       selectExpression.GroupBy.ToList(),
                                                       selectExpression.Having,
                                                       orderings: newOrderings,
                                                       limit: null,
                                                       offset: null);
            var rowOrderings = oldOrderings.Count != 0 ? oldOrderings
                : new[] { new OrderingExpression(new SqlFragmentExpression("(SELECT 1)"), true) };

            _ = selectExpression.PushdownIntoSubquery();    // .NET 6 该方法已无返回值

            var subQuery   = (SelectExpression)selectExpression.Tables[0];
            var projection = new RowNumberExpression(Array.Empty <SqlExpression>(), rowOrderings, oldOffset.TypeMapping);
            var left       = GenerateOuterColumnAccessor(subQuery, projection, "row");

            selectExpression.ApplyPredicate(sqlExpressionFactory.GreaterThan(left, oldOffset));

            if (oldLimit != null)
            {
                if (oldOrderings.Count == 0)
                {
                    selectExpression.ApplyPredicate(sqlExpressionFactory.LessThanOrEqual(left, sqlExpressionFactory.Add(oldOffset, oldLimit)));
                }
                else
                {
                    // 这里不支持子查询的 OrderBy 操作
                    selectExpression.ApplyLimit(oldLimit);
                }
            }
            return(selectExpression);
        }
コード例 #3
0
        public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            if (method == IPAddressParse)
            {
                return(_sqlExpressionFactory.Convert(arguments[0], typeof(IPAddress), _sqlExpressionFactory.FindMapping(typeof(IPAddress))));
            }

            if (method == PhysicalAddressParse)
            {
                return(_sqlExpressionFactory.Convert(arguments[0], typeof(PhysicalAddress), _sqlExpressionFactory.FindMapping(typeof(PhysicalAddress))));
            }

            if (method.DeclaringType != typeof(NpgsqlNetworkExtensions))
            {
                return(null);
            }

            return(method.Name switch
            {
                nameof(NpgsqlNetworkExtensions.LessThan) => _sqlExpressionFactory.LessThan(arguments[1], arguments[2]),
                nameof(NpgsqlNetworkExtensions.LessThanOrEqual) => _sqlExpressionFactory.LessThanOrEqual(arguments[1], arguments[2]),
                nameof(NpgsqlNetworkExtensions.GreaterThanOrEqual) => _sqlExpressionFactory.GreaterThanOrEqual(arguments[1], arguments[2]),
                nameof(NpgsqlNetworkExtensions.GreaterThan) => _sqlExpressionFactory.GreaterThan(arguments[1], arguments[2]),

                nameof(NpgsqlNetworkExtensions.ContainedBy) => BoolReturningOnTwoNetworkTypes("<<"),
                nameof(NpgsqlNetworkExtensions.ContainedByOrEqual) => BoolReturningOnTwoNetworkTypes("<<="),
                nameof(NpgsqlNetworkExtensions.Contains) => BoolReturningOnTwoNetworkTypes(">>"),
                nameof(NpgsqlNetworkExtensions.ContainsOrEqual) => BoolReturningOnTwoNetworkTypes(">>="),
                nameof(NpgsqlNetworkExtensions.ContainsOrContainedBy) => BoolReturningOnTwoNetworkTypes("&&"),

                // TODO: Hack, see #1118
                nameof(NpgsqlNetworkExtensions.BitwiseNot) => new SqlUnaryExpression(ExpressionType.Negate,
                                                                                     arguments[1],
                                                                                     arguments[1].Type,
                                                                                     arguments[1].TypeMapping),

                nameof(NpgsqlNetworkExtensions.BitwiseAnd) => _sqlExpressionFactory.And(arguments[1], arguments[2]),
                nameof(NpgsqlNetworkExtensions.BitwiseOr) => _sqlExpressionFactory.Or(arguments[1], arguments[2]),

                // Add/Subtract accept inet + int, so we can't use the default type mapping inference logic which assumes
                // same-typed operands
                nameof(NpgsqlNetworkExtensions.Add)
                => new SqlBinaryExpression(
                    ExpressionType.Add,
                    _sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[1]),
                    _sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[2]),
                    arguments[1].Type,
                    arguments[1].TypeMapping),

                nameof(NpgsqlNetworkExtensions.Subtract) when arguments[2].Type == typeof(int)
                private Expression VisitSelect(SelectExpression selectExpression)
                {
                    var oldOffset = selectExpression.Offset;

                    if (oldOffset == null)
                    {
                        return(selectExpression);
                    }

                    var oldLimit     = selectExpression.Limit;
                    var oldOrderings = selectExpression.Orderings;
                    //order by in subQuery without TOP N is invalid.
                    var newOrderings = oldOrderings.Count > 0 && (oldLimit != null || selectExpression == root)
                        ? oldOrderings.ToList()
                        : new List <OrderingExpression>();

                    selectExpression = selectExpression.Update(selectExpression.Projection.ToList(),
                                                               selectExpression.Tables.ToList(),
                                                               selectExpression.Predicate,
                                                               selectExpression.GroupBy.ToList(),
                                                               selectExpression.Having,
                                                               orderings: newOrderings,
                                                               limit: null,
                                                               offset: null,
                                                               selectExpression.IsDistinct,
                                                               selectExpression.Alias);
                    var rowOrderings = oldOrderings.Count != 0 ? oldOrderings
                        : new[] { new OrderingExpression(new SqlFragmentExpression("(SELECT 1)"), true) };

                    _ = selectExpression.PushdownIntoSubquery();
                    var subQuery   = (SelectExpression)selectExpression.Tables[0];
                    var projection = new RowNumberExpression(Array.Empty <SqlExpression>(), rowOrderings, oldOffset.TypeMapping);
                    var left       = GenerateOuterColumnAccessor(subQuery, projection, "row");

                    selectExpression.ApplyPredicate(sqlExpressionFactory.GreaterThan(left, oldOffset));
                    if (oldLimit != null)
                    {
                        if (oldOrderings.Count == 0)
                        {
                            selectExpression.ApplyPredicate(sqlExpressionFactory.LessThanOrEqual(left, sqlExpressionFactory.Add(oldOffset, oldLimit)));
                        }
                        else
                        {
                            //the above one not working when used as subQuery with orderBy
                            selectExpression.ApplyLimit(oldLimit);
                        }
                    }
                    return(selectExpression);
                }
コード例 #5
0
        public SqlExpression Translate(SqlExpression instance, MethodInfo method, IList <SqlExpression> arguments)
        {
            method = method.OnInterface(typeof(IGeometry));
            if (_methodToFunctionName.TryGetValue(method, out var functionName))
            {
                SqlExpression translation = _sqlExpressionFactory.Function(
                    functionName,
                    new[] { instance }.Concat(arguments),
                    method.ReturnType);

                if (method.ReturnType == typeof(bool))
                {
                    translation = _sqlExpressionFactory.Case(
                        new[]
                    {
                        new CaseWhenClause(_sqlExpressionFactory.IsNotNull(instance), translation)
                    },
                        null);
                }

                return(translation);
            }

            if (Equals(method, _getGeometryN))
            {
                return(_sqlExpressionFactory.Function(
                           "GeometryN",
                           new[] {
                    instance,
                    _sqlExpressionFactory.Add(
                        arguments[0],
                        _sqlExpressionFactory.Constant(1))
                },
                           method.ReturnType));
            }

            if (Equals(method, _isWithinDistance))
            {
                return(_sqlExpressionFactory.LessThanOrEqual(
                           _sqlExpressionFactory.Function(
                               "Distance",
                               new[] { instance, arguments[0] },
                               typeof(double)),
                           arguments[1]));
            }

            return(null);
        }
コード例 #6
0
        /// <inheritdoc/>
        public virtual SqlExpression?Translate(
            SqlExpression?instance,
            MethodInfo method,
            IReadOnlyList <SqlExpression> arguments,
            IDiagnosticsLogger <DbLoggerCategory.Query> logger)
        {
            Check.NotNull(method, nameof(method));
            Check.NotNull(arguments, nameof(arguments));
            Check.NotNull(logger, nameof(logger));

            if (_methodInfoDatePartMapping.TryGetValue(method, out var value))
            {
                var start = _sqlExpressionFactory.GreaterThanOrEqual(arguments[0], arguments[1]);
                var end   = _sqlExpressionFactory.LessThanOrEqual(arguments[0], arguments[2]);
                return(_sqlExpressionFactory.AndAlso(start, end));
            }

            return(null);
        }
コード例 #7
0
        public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            if (typeof(Geometry).IsAssignableFrom(method.DeclaringType))
            {
                var geometryExpressions = new[] { instance }.Concat(
                    arguments.Where(e => typeof(Geometry).IsAssignableFrom(e.Type)));
                var typeMapping = ExpressionExtensions.InferTypeMapping(geometryExpressions.ToArray());

                Debug.Assert(typeMapping != null, "At least one argument must have typeMapping.");
                var storeType   = typeMapping.StoreType;
                var isGeography = string.Equals(storeType, "geography", StringComparison.OrdinalIgnoreCase);

                if (_methodToFunctionName.TryGetValue(method, out var functionName) ||
                    (!isGeography && _geometryMethodToFunctionName.TryGetValue(method, out functionName)))
                {
                    instance = _sqlExpressionFactory.ApplyTypeMapping(
                        instance, _typeMappingSource.FindMapping(instance.Type, storeType));

                    var typeMappedArguments = new List <SqlExpression>();
                    foreach (var argument in arguments)
                    {
                        typeMappedArguments.Add(
                            _sqlExpressionFactory.ApplyTypeMapping(
                                argument,
                                typeof(Geometry).IsAssignableFrom(argument.Type)
                                    ? _typeMappingSource.FindMapping(argument.Type, storeType)
                                    : _typeMappingSource.FindMapping(argument.Type)));
                    }

                    var resultTypeMapping = typeof(Geometry).IsAssignableFrom(method.ReturnType)
                        ? _typeMappingSource.FindMapping(method.ReturnType, storeType)
                        : _typeMappingSource.FindMapping(method.ReturnType);

                    return(_sqlExpressionFactory.Function(
                               instance,
                               functionName,
                               Simplify(typeMappedArguments, isGeography),
                               method.ReturnType,
                               resultTypeMapping));
                }

                if (Equals(method, _getGeometryN))
                {
                    return(_sqlExpressionFactory.Function(
                               instance,
                               "STGeometryN",
                               new[] {
                        _sqlExpressionFactory.Add(
                            arguments[0],
                            _sqlExpressionFactory.Constant(1))
                    },
                               method.ReturnType,
                               _typeMappingSource.FindMapping(method.ReturnType, storeType)));
                }

                if (Equals(method, _isWithinDistance))
                {
                    instance = _sqlExpressionFactory.ApplyTypeMapping(
                        instance, _typeMappingSource.FindMapping(instance.Type, storeType));

                    var typeMappedArguments = new List <SqlExpression>();
                    foreach (var argument in arguments)
                    {
                        typeMappedArguments.Add(
                            _sqlExpressionFactory.ApplyTypeMapping(
                                argument,
                                typeof(Geometry).IsAssignableFrom(argument.Type)
                                    ? _typeMappingSource.FindMapping(argument.Type, storeType)
                                    : _typeMappingSource.FindMapping(argument.Type)));
                    }

                    return(_sqlExpressionFactory.LessThanOrEqual(
                               _sqlExpressionFactory.Function(
                                   instance,
                                   "STDistance",
                                   Simplify(new[] { typeMappedArguments[0] }, isGeography),
                                   typeof(double)),
                               typeMappedArguments[1]));
                }
            }

            return(null);
        }
コード例 #8
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual SqlExpression?Translate(
            SqlExpression?instance,
            MethodInfo method,
            IReadOnlyList <SqlExpression> arguments,
            IDiagnosticsLogger <DbLoggerCategory.Query> logger)
        {
            Check.NotNull(method, nameof(method));
            Check.NotNull(arguments, nameof(arguments));
            Check.NotNull(logger, nameof(logger));

            if (typeof(Geometry).IsAssignableFrom(method.DeclaringType) &&
                instance != null)
            {
                var geometryExpressions = new[] { instance }.Concat(
                    arguments.Where(e => typeof(Geometry).IsAssignableFrom(e.Type)));
                var typeMapping = ExpressionExtensions.InferTypeMapping(geometryExpressions.ToArray());

                Check.DebugAssert(typeMapping != null, "At least one argument must have typeMapping.");
                var storeType   = typeMapping.StoreType;
                var isGeography = string.Equals(storeType, "geography", StringComparison.OrdinalIgnoreCase);

                if (_methodToFunctionName.TryGetValue(method, out var functionName) ||
                    (!isGeography && _geometryMethodToFunctionName.TryGetValue(method, out functionName)))
                {
                    instance = _sqlExpressionFactory.ApplyTypeMapping(
                        instance, _typeMappingSource.FindMapping(instance.Type, storeType));

                    var typeMappedArguments = new List <SqlExpression>();
                    foreach (var argument in arguments)
                    {
                        typeMappedArguments.Add(
                            _sqlExpressionFactory.ApplyTypeMapping(
                                argument,
                                typeof(Geometry).IsAssignableFrom(argument.Type)
                                    ? _typeMappingSource.FindMapping(argument.Type, storeType)
                                    : _typeMappingSource.FindMapping(argument.Type)));
                    }

                    var resultTypeMapping = typeof(Geometry).IsAssignableFrom(method.ReturnType)
                        ? _typeMappingSource.FindMapping(method.ReturnType, storeType)
                        : _typeMappingSource.FindMapping(method.ReturnType);

                    var finalArguments = Simplify(typeMappedArguments, isGeography);

                    var argumentsPropagateNullability = functionName == "STBuffer"
                        ? new[] { false }
                        : functionName == "STRelate"
                            ? new[] { true, false }
                            : finalArguments.Select(a => true).ToArray();

                    return(_sqlExpressionFactory.Function(
                               instance,
                               functionName,
                               finalArguments,
                               nullable: true,
                               instancePropagatesNullability: true,
                               argumentsPropagateNullability,
                               method.ReturnType,
                               resultTypeMapping));
                }

                if (Equals(method, _getGeometryN))
                {
                    return(_sqlExpressionFactory.Function(
                               instance,
                               "STGeometryN",
                               new[]
                    {
                        _sqlExpressionFactory.Add(
                            arguments[0],
                            _sqlExpressionFactory.Constant(1))
                    },
                               nullable: true,
                               instancePropagatesNullability: true,
                               argumentsPropagateNullability: new[] { false },
                               method.ReturnType,
                               _typeMappingSource.FindMapping(method.ReturnType, storeType)));
                }

                if (Equals(method, _isWithinDistance))
                {
                    instance = _sqlExpressionFactory.ApplyTypeMapping(
                        instance, _typeMappingSource.FindMapping(instance.Type, storeType));

                    var typeMappedArguments = new List <SqlExpression>();
                    foreach (var argument in arguments)
                    {
                        typeMappedArguments.Add(
                            _sqlExpressionFactory.ApplyTypeMapping(
                                argument,
                                typeof(Geometry).IsAssignableFrom(argument.Type)
                                    ? _typeMappingSource.FindMapping(argument.Type, storeType)
                                    : _typeMappingSource.FindMapping(argument.Type)));
                    }

                    var finalArguments = Simplify(new[] { typeMappedArguments[0] }, isGeography);

                    return(_sqlExpressionFactory.LessThanOrEqual(
                               _sqlExpressionFactory.Function(
                                   instance,
                                   "STDistance",
                                   finalArguments,
                                   nullable: true,
                                   instancePropagatesNullability: true,
                                   argumentsPropagateNullability: finalArguments.Select(a => true),
                                   typeof(double)),
                               typeMappedArguments[1]));
                }
            }

            return(null);
        }
コード例 #9
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual SqlExpression?Translate(
        SqlExpression?instance,
        MethodInfo method,
        IReadOnlyList <SqlExpression> arguments,
        IDiagnosticsLogger <DbLoggerCategory.Query> logger)
    {
        if (instance != null)
        {
            if (MethodToFunctionName.TryGetValue(method, out var functionName))
            {
                var finalArguments = new[] { instance }.Concat(arguments);

                if (method.ReturnType == typeof(bool))
                {
                    var nullCheck = (SqlExpression)_sqlExpressionFactory.IsNotNull(instance);
                    foreach (var argument in arguments)
                    {
                        nullCheck = _sqlExpressionFactory.AndAlso(
                            nullCheck,
                            _sqlExpressionFactory.IsNotNull(argument));
                    }

                    return(_sqlExpressionFactory.Case(
                               new[]
                    {
                        new CaseWhenClause(
                            nullCheck,
                            _sqlExpressionFactory.Function(
                                functionName,
                                finalArguments,
                                nullable: false,
                                finalArguments.Select(a => false),
                                method.ReturnType))
                    },
                               null));
                }

                return(_sqlExpressionFactory.Function(
                           functionName,
                           finalArguments,
                           nullable: true,
                           finalArguments.Select(a => true),
                           method.ReturnType));
            }

            if (Equals(method, GetGeometryN))
            {
                return(_sqlExpressionFactory.Function(
                           "GeometryN",
                           new[]
                {
                    instance,
                    _sqlExpressionFactory.Add(
                        arguments[0],
                        _sqlExpressionFactory.Constant(1))
                },
                           nullable: true,
                           argumentsPropagateNullability: new[] { true, true },
                           method.ReturnType));
            }

            if (Equals(method, IsWithinDistance))
            {
                return(_sqlExpressionFactory.LessThanOrEqual(
                           _sqlExpressionFactory.Function(
                               "Distance",
                               new[] { instance, arguments[0] },
                               nullable: true,
                               argumentsPropagateNullability: new[] { true, true },
                               typeof(double)),
                           arguments[1]));
            }
        }

        return(null);
    }
コード例 #10
0
        public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            Check.NotNull(method, nameof(method));
            Check.NotNull(arguments, nameof(arguments));

            if (_methodToFunctionName.TryGetValue(method, out var functionName))
            {
                var finalArguments = new[] { instance }.Concat(arguments);

                if (method.ReturnType == typeof(bool))
                {
                    var nullCheck = (SqlExpression)_sqlExpressionFactory.IsNotNull(instance);
                    foreach (var argument in arguments)
                    {
                        nullCheck = _sqlExpressionFactory.AndAlso(
                            nullCheck,
                            _sqlExpressionFactory.IsNotNull(argument));
                    }

                    return(_sqlExpressionFactory.Case(
                               new[]
                    {
                        new CaseWhenClause(
                            nullCheck,
                            _sqlExpressionFactory.Function(
                                functionName,
                                finalArguments,
                                nullResultAllowed: false,
                                finalArguments.Select(a => false),
                                method.ReturnType))
                    },
                               null));
                }

                return(_sqlExpressionFactory.Function(
                           functionName,
                           finalArguments,
                           nullResultAllowed: true,
                           finalArguments.Select(a => true),
                           method.ReturnType));
            }

            if (Equals(method, _getGeometryN))
            {
                return(_sqlExpressionFactory.Function(
                           "GeometryN",
                           new[]
                {
                    instance,
                    _sqlExpressionFactory.Add(
                        arguments[0],
                        _sqlExpressionFactory.Constant(1))
                },
                           nullResultAllowed: true,
                           argumentsPropagateNullability: new[] { true, true },
                           method.ReturnType));
            }

            if (Equals(method, _isWithinDistance))
            {
                return(_sqlExpressionFactory.LessThanOrEqual(
                           _sqlExpressionFactory.Function(
                               "Distance",
                               new[] { instance, arguments[0] },
                               nullResultAllowed: true,
                               argumentsPropagateNullability: new[] { true, true },
                               typeof(double)),
                           arguments[1]));
            }

            return(null);
        }
        public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            if (typeof(Geometry).IsAssignableFrom(method.DeclaringType))
            {
                var geometryExpressions = new[] { instance }.Concat(
                    arguments.Where(e => typeof(Geometry).IsAssignableFrom(e.Type)));
                var typeMapping = ExpressionExtensions.InferTypeMapping(geometryExpressions.ToArray());

                Debug.Assert(typeMapping != null, "At least one argument must have typeMapping.");
                var storeType = typeMapping.StoreType;

                if (_methodToFunctionName.TryGetValue(method, out var functionName) ||
                    _geometryMethodToFunctionName.TryGetValue(method, out functionName))
                {
                    instance = _sqlExpressionFactory.ApplyTypeMapping(
                        instance,
                        _typeMappingSource.FindMapping(instance.Type, storeType));

                    var typeMappedArguments = new List <SqlExpression>
                    {
                        instance
                    };

                    foreach (var argument in arguments)
                    {
                        typeMappedArguments.Add(
                            _sqlExpressionFactory.ApplyTypeMapping(
                                argument,
                                typeof(Geometry).IsAssignableFrom(argument.Type)
                                    ? _typeMappingSource.FindMapping(argument.Type, storeType)
                                    : _typeMappingSource.FindMapping(argument.Type)));
                    }

                    var resultTypeMapping = typeof(Geometry).IsAssignableFrom(method.ReturnType)
                        ? _typeMappingSource.FindMapping(method.ReturnType, storeType)
                        : _typeMappingSource.FindMapping(method.ReturnType);

                    return(_sqlExpressionFactory.Function(
                               functionName,
                               typeMappedArguments,
                               method.ReturnType,
                               resultTypeMapping));
                }

                if (Equals(method, _getGeometryN))
                {
                    return(_sqlExpressionFactory.Function(
                               "ST_GeometryN",
                               new[]
                    {
                        instance,
                        _sqlExpressionFactory.Add(
                            arguments[0],
                            _sqlExpressionFactory.Constant(1))
                    },
                               method.ReturnType,
                               _typeMappingSource.FindMapping(method.ReturnType, storeType)));
                }

                if (Equals(method, _distance))
                {
                    return(GetDistanceCallBySrid(
                               instance,
                               arguments[0],
                               method.ReturnType,
                               _typeMappingSource.FindMapping(method.ReturnType, storeType)));
                }

                if (Equals(method, _isWithinDistance))
                {
                    return(_sqlExpressionFactory.LessThanOrEqual(
                               GetDistanceCallBySrid(
                                   instance,
                                   arguments[0],
                                   _distance.ReturnType,
                                   _typeMappingSource.FindMapping(_distance.ReturnType)),
                               arguments[1]));
                }
            }

            return(null);
        }