在項(xiàng)目中我們經(jīng)常遇到將數(shù)據(jù)庫(kù)的數(shù)據(jù)取到后再次進(jìn)行篩選過(guò)濾的情況。LINQ to Entity提供了統(tǒng)一的查詢(xún)接口并且可以高效的完成工作,但是對(duì)于我們常在SQL中使用的%和_這樣的通配符并沒(méi)有支持。我們只能通過(guò)String.Contains方法來(lái)實(shí)現(xiàn)簡(jiǎn)單的通配。使用String.Contains方法是無(wú)法達(dá)到在查詢(xún)串中使用通配符的目的的。正則表達(dá)式雖然晦澀難懂,但功能十分強(qiáng)大,解決個(gè)統(tǒng)配符綽綽有余。
創(chuàng)新互聯(lián)專(zhuān)注為客戶(hù)提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、寧縣網(wǎng)絡(luò)推廣、小程序開(kāi)發(fā)、寧縣網(wǎng)絡(luò)營(yíng)銷(xiāo)、寧縣企業(yè)策劃、寧縣品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪(fǎng)、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供寧縣建站搭建服務(wù),24小時(shí)服務(wù)熱線(xiàn):18980820575,官方網(wǎng)址:www.cdcxhl.com
代碼如下:
public static class LINQHelper { ////// The all regex meta chars /// private static string[] REGEX_META_CHARS = { "\\", ".", "^", "$", "*", "+", "?", "{", "}", "(", ")", "[", "]" }; ////// Like method work as SQL like /// /// The search string /// The SQL pattern ///Whether match or not 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); } } ////// Like method work as SQL like /// /// The search string /// The SQL pattern /// The escape char ///Whether match or not 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); } } ////// Replace wildcards /// /// The replacement string /// The wildcard /// The replace wild char to /// The escape char ///The converted search value 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()); } ////// Escape regex meta chars /// /// The replacement string ///The converted search value 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; } }
首先,要將查詢(xún)串中所有正則表達(dá)式的元字符轉(zhuǎn)義為普通字符,這樣才能安全的使用正則表達(dá)式進(jìn)行匹配。
然后,將”_”和”%”替換成相應(yīng)的正則表達(dá)式,即”_”替換成”.”,”%”替換成”.*”。這里還考慮到SQL的LIKE語(yǔ)句也有轉(zhuǎn)義符功能,即如果使用ESCAPE子句則LIKE串中轉(zhuǎn)義符后的”_”和”%”變?yōu)槠胀ㄗ址皇峭ㄅ浞K援?dāng)使用轉(zhuǎn)義符時(shí)處理如下:
將所有不以轉(zhuǎn)義符引導(dǎo)的通配符替換。
再將轉(zhuǎn)義符引導(dǎo)的通配符的轉(zhuǎn)義符去掉,即將通配符轉(zhuǎn)義為普通字符。
以下是幾個(gè)轉(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)點(diǎn):我們可以在LINQ語(yǔ)句的條件中方便的使用Like方法去過(guò)濾數(shù)據(jù),LINQ語(yǔ)句整體上會(huì)保持很好的可讀性。
缺點(diǎn):Like 方法會(huì)被調(diào)用n次(n取決于數(shù)據(jù)量),解析SQL pattern到正則表達(dá)式pattern的代碼就要被重復(fù)執(zhí)行n次。因此當(dāng)數(shù)據(jù)量過(guò)大時(shí)解析pattern會(huì)消耗一定的資源。當(dāng)然這可以通過(guò)一些方法去解決,如緩存解析結(jié)果,或改為傳入就是解析好的正則表達(dá)式等。