From f15d60aaab054ae17e6b5f5bcbbc7b22c140c04a Mon Sep 17 00:00:00 2001 From: Christopher Jolly Date: Thu, 20 Apr 2023 01:18:54 +0800 Subject: [PATCH] Fix escaping wild chars. Use the correct form to escape. Also the LIKE clause does nt have an ESCAPE clause to set the escape char so set that to null --- .../Internal/JetStringMethodTranslator.cs | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetStringMethodTranslator.cs b/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetStringMethodTranslator.cs index 3c89871..45704f6 100644 --- a/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetStringMethodTranslator.cs +++ b/src/EFCore.Jet/Query/ExpressionTranslators/Internal/JetStringMethodTranslator.cs @@ -132,7 +132,7 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal ? _sqlExpressionFactory.Like( instance, _sqlExpressionFactory.Constant($"%{EscapeLikePattern(patternValue)}%"), - _sqlExpressionFactory.Constant(LikeEscapeString)) + null) : _sqlExpressionFactory.Like(instance, _sqlExpressionFactory.Constant($"%{patternValue}%")); } @@ -145,7 +145,7 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal "INSTR", new[] { _sqlExpressionFactory.Constant(1), instance, pattern, _sqlExpressionFactory.Constant(1) }, nullable: true, - argumentsPropagateNullability: new[] { true,true, true, true }, + argumentsPropagateNullability: new[] { true, true, true, true }, typeof(int)), _sqlExpressionFactory.Constant(0))); } @@ -186,7 +186,7 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal Equals(method, _trimEndMethodInfoWithCharArrayArg) && ((arguments[0] as SqlConstantExpression)?.Value as Array)?.Length == 0) { - return _sqlExpressionFactory.Function("RTRIM", new[] { instance }, true, new[] { true }, + return _sqlExpressionFactory.Function("RTRIM", new[] { instance }, true, new[] { true }, instance.Type, instance.TypeMapping); } @@ -346,7 +346,7 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal startsWith ? EscapeLikePattern(patternValue) + '%' : '%' + EscapeLikePattern(patternValue)), - _sqlExpressionFactory.Constant(LikeEscapeString)) + null) : _sqlExpressionFactory.Like( instance, _sqlExpressionFactory.Constant(startsWith ? patternValue + '%' : '%' + patternValue)); @@ -405,7 +405,7 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal searchExpression = _sqlExpressionFactory.ApplyTypeMapping(searchExpression, stringTypeMapping); instance = _sqlExpressionFactory.ApplyTypeMapping(instance, stringTypeMapping); - var charIndexArguments = new List { instance, searchExpression}; + var charIndexArguments = new List { instance, searchExpression }; if (startIndex is not null) { @@ -465,22 +465,29 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal charIndexExpression); } + //Extra resources + // https://support.microsoft.com/en-us/office/like-operator-b2f7ef03-9085-4ffb-9829-eef18358e931 + // https://support.microsoft.com/en-us/office/access-wildcard-character-reference-af00c501-7972-40ee-8889-e18abaad12d1 + // https://support.microsoft.com/en-us/office/use-wildcards-in-queries-and-parameters-in-access-ec057a45-78b1-4d16-8c20-242cde582e0b + //These are the characters to escape in LIKE pattern private static bool IsLikeWildChar(char c) - => c == '%' || c == '_' || c == '['; + => c == '%' || c == '_' || c == '[' || c == '^' || c == '?' || c == '#' || c == '*'; private static string EscapeLikePattern(string pattern) { var builder = new StringBuilder(); - for (var i = 0; i < pattern.Length; i++) + foreach (var c in pattern) { - var c = pattern[i]; - if (IsLikeWildChar(c) - || c == LikeEscapeChar) + if (IsLikeWildChar(c)) { - builder.Append(LikeEscapeChar); + builder.Append('['); + builder.Append(c); + builder.Append(']'); + } + else + { + builder.Append(c); } - - builder.Append(c); } return builder.ToString();