public virtual Expression Translate(MethodCallExpression methodCallExpression) { if (!methodCallExpression.Method.Equals(_methodInfo)) { return(null); } var argument0 = methodCallExpression.Arguments[0]; // If Contains() is being invoked on a citext, ensure that the string argument is explicitly cast into a // citext (instead of the default text for a CLR string) as otherwise PostgreSQL prefers the text variant of // the ambiguous call STRPOS(citext, text) and the search will be case-sensitive. See #384. if (argument0 != null && methodCallExpression.Object?.FindProperty(typeof(string))?.GetConfiguredColumnType() == "citext") { argument0 = new ExplicitStoreTypeCastExpression(argument0, typeof(string), "citext"); } return(Expression.GreaterThan( new SqlFunctionExpression("STRPOS", typeof(int), new[] { methodCallExpression.Object, argument0 }), Expression.Constant(0) )); }
public virtual Expression Translate(MethodCallExpression e) { if (!e.Method.Equals(_methodInfo) || e.Object == null) { return(null); } var constantPatternExpr = e.Arguments[0] as ConstantExpression; if (constantPatternExpr != null) { // The pattern is constant. Escape all special characters (%, _, \) in C# and send // a simple LIKE return(new LikeExpression( e.Object, Expression.Constant(Regex.Replace((string)constantPatternExpr.Value, @"([%_\\])", @"\$1") + '%') )); } // The pattern isn't a constant (i.e. parameter, database column...). // First run LIKE against the *unescaped* pattern (which will efficiently use indices), // but then add another test to filter out false positives. var pattern = e.Arguments[0]; Expression leftExpr = new SqlFunctionExpression("LEFT", typeof(string), new[] { e.Object, new SqlFunctionExpression("LENGTH", typeof(int), new[] { pattern }), }); // If StartsWith is being invoked on a citext, the LEFT() function above will return a reglar text // and the comparison will be case-sensitive. So we need to explicitly cast LEFT()'s return type // to citext. See #319. if (e.Object.FindProperty(typeof(string))?.GetConfiguredColumnType() == "citext") { leftExpr = new ExplicitStoreTypeCastExpression(leftExpr, typeof(string), "citext"); } return(Expression.AndAlso( new LikeExpression(e.Object, Expression.Add(pattern, Expression.Constant("%"), _concat)), Expression.Equal( leftExpr, pattern ) )); }