您好,登錄后才能下訂單哦!
在項目中我們經(jīng)常遇到將數(shù)據(jù)庫的數(shù)據(jù)取到后再次進行篩選過濾的情況。LINQ to Entity提供了統(tǒng)一的查詢接口并且可以高效的完成工作,但是對于我們常在SQL中使用的%和_這樣的通配符并沒有支持。我們只能通過String.Contains方法來實現(xiàn)簡單的通配。使用String.Contains方法是無法達到在查詢串中使用通配符的目的的。正則表達式雖然晦澀難懂,但功能十分強大,解決個統(tǒng)配符綽綽有余。
代碼如下:
public static class LINQHelper { /// <summary> /// The all regex meta chars /// </summary> private static string[] REGEX_META_CHARS = { "\\", ".", "^", "$", "*", "+", "?", "{", "}", "(", ")", "[", "]" }; /// <summary> /// Like method work as SQL like /// </summary> /// <param name="searchString">The search string</param> /// <param name="sqlPattern">The SQL pattern</param> /// <returns>Whether match or not</returns> public static bool Like(this string searchString, string sqlPattern) { if (searchString == null) { return false; } else { string convertedPattern = EscapeRegexMetaChars(sqlPattern).Replace("_", ".").Replace("%", ".*"); convertedPattern = String.Format("^{0}$", convertedPattern); return Regex.IsMatch(searchString, convertedPattern, RegexOptions.Singleline); } } /// <summary> /// Like method work as SQL like /// </summary> /// <param name="searchString">The search string</param> /// <param name="sqlPattern">The SQL pattern</param> /// <param name="escapeChar">The escape char</param> /// <returns>Whether match or not</returns> public static bool Like(this string searchString, string sqlPattern, char escapeChar) { if (searchString == null) { return false; } else { string convertedPattern = EscapeRegexMetaChars(sqlPattern); convertedPattern = ReplaceWildcards(convertedPattern, '_', ".", escapeChar); convertedPattern = ReplaceWildcards(convertedPattern, '%', ".*", escapeChar); convertedPattern = String.Format("^{0}$", convertedPattern); return Regex.IsMatch(searchString, convertedPattern, RegexOptions.Singleline); } } /// <summary> /// Replace wildcards /// </summary> /// <param name="replacement">The replacement string</param> /// <param name="wildcard">The wildcard</param> /// <param name="replaceTo">The replace wild char to</param> /// <param name="escapeChar">The escape char</param> /// <returns>The converted search value</returns> private static string ReplaceWildcards(string replacement, char wildcard, string replaceTo, char escapeChar) { string regexExpression = String.Format("(^|[^{0}])({1}+)", escapeChar, wildcard); return Regex.Replace(replacement, regexExpression, match => String.Format("{0}{1}", match.Groups[1].Value, match.Groups[2].Value.Replace(wildcard.ToString(), replaceTo))) .Replace(string.Format("{0}{1}", escapeChar, wildcard), wildcard.ToString()); } /// <summary> /// Escape regex meta chars /// </summary> /// <param name="replacement">The replacement string</param> /// <returns>The converted search value</returns> private static string EscapeRegexMetaChars(string replacement) { string resultString = replacement; foreach (string metaChar in REGEX_META_CHARS) { resultString = resultString.Replace(metaChar, string.Format(@"\{0}", metaChar)); } return resultString; } }
首先,要將查詢串中所有正則表達式的元字符轉(zhuǎn)義為普通字符,這樣才能安全的使用正則表達式進行匹配。
然后,將”_”和”%”替換成相應的正則表達式,即”_”替換成”.”,”%”替換成”.*”。這里還考慮到SQL的LIKE語句也有轉(zhuǎn)義符功能,即如果使用ESCAPE子句則LIKE串中轉(zhuǎn)義符后的”_”和”%”變?yōu)槠胀ㄗ址皇峭ㄅ浞?。所以當使用轉(zhuǎn)義符時處理如下:
將所有不以轉(zhuǎn)義符引導的通配符替換。
再將轉(zhuǎn)義符引導的通配符的轉(zhuǎn)義符去掉,即將通配符轉(zhuǎn)義為普通字符。
以下是幾個轉(zhuǎn)換的例子:
LIKE ‘A_B’ 轉(zhuǎn)換為 A.B
LIKE ‘A%B’ 轉(zhuǎn)換為 A.*B
LIKE ‘A~_B’ ESCAPE ‘~’ 轉(zhuǎn)換為 A_B
LIKE ‘A.B’ 轉(zhuǎn)換為 A/.B
優(yōu)點:我們可以在LINQ語句的條件中方便的使用Like方法去過濾數(shù)據(jù),LINQ語句整體上會保持很好的可讀性。
缺點:Like 方法會被調(diào)用n次(n取決于數(shù)據(jù)量),解析SQL pattern到正則表達式pattern的代碼就要被重復執(zhí)行n次。因此當數(shù)據(jù)量過大時解析pattern會消耗一定的資源。當然這可以通過一些方法去解決,如緩存解析結(jié)果,或改為傳入就是解析好的正則表達式等。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。