像LINQ to Entities中的运算符或使用通配符一样
我正在使用LINQ 2实体。 以下是问题:
string str = '%test%.doc%' .Contains(str) // converts this into LIKE '%~%test~%.doc~%%'
预期转换:LIKE’%test%.doc%’
如果它是LINQ 2 SQL,我可以使用SqlMethods.Like,因为有人在我之前的问题中回答了它。 但是现在因为我使用L2E而不是L2S,我需要其他解决方案。
您可以尝试使用本文 ,其中作者描述了如何在LINQ to Entities中使用通配符构建LIKE语句。
编辑:由于原始链接现已死亡,这里是原始扩展类(根据评论中的Jon Koeter )和用法示例。
延期:
public static class LinqHelper { //Support IQueryable (Linq to Entities) public static IQueryable WhereLike (this IQueryable source, Expression> valueSelector, string value, char wildcard) { return source.Where(BuildLikeExpression(valueSelector, value, wildcard)); } //Support IEnumerable (Linq to objects) public static IEnumerable WhereLike (this IEnumerable sequence, Func expression, string value, char wildcard) { var regEx = WildcardToRegex(value, wildcard); //Prevent multiple enumeration: var arraySequence = sequence as TSource[] ?? sequence.ToArray(); try { return arraySequence.Where(item => Regex.IsMatch(expression(item), regEx)); } catch (ArgumentNullException) { return arraySequence; } } //Used for the IEnumerable support private static string WildcardToRegex(string value, char wildcard) { return "(?i:^" + Regex.Escape(value).Replace("\" + wildcard, "." + wildcard) + "$)"; } //Used for the IQueryable support private static Expression> BuildLikeExpression(Expression> valueSelector, string value, char wildcard) { if (valueSelector == null) throw new ArgumentNullException("valueSelector"); var method = GetLikeMethod(value, wildcard); value = value.Trim(wildcard); var body = Expression.Call(valueSelector.Body, method, Expression.Constant(value)); var parameter = valueSelector.Parameters.Single(); return Expression.Lambda>(body, parameter); } private static MethodInfo GetLikeMethod(string value, char wildcard) { var methodName = "Equals"; var textLength = value.Length; value = value.TrimEnd(wildcard); if (textLength > value.Length) { methodName = "StartsWith"; textLength = value.Length; } value = value.TrimStart(wildcard); if (textLength > value.Length) { methodName = (methodName == "StartsWith") ? "Contains" : "EndsWith"; } var stringType = typeof(string); return stringType.GetMethod(methodName, new[] { stringType }); } }
用法示例:
string strEmailToFind = "%@yahoo.com" IQueryable myUsers = entities.Users.WhereLike(u => u.EmailAddress, strEmailToFind, '%');
或者,如果您希望您的用户更习惯使用Windows资源管理器风格的通配符:
string strEmailToFind = "*@yahoo.com" IQueryable myUsers = entities.Users.WhereLike(u => u.EmailAddress, strEmailToFind, '*');
SQL方法PATINDEX提供与LIKE相同的function。 因此,您可以使用SqlFunctions.PatIndex方法:
.Where(x => SqlFunctions.PatIndex("%test%.doc%", x.MySearchField) > 0)
继Magnus的正确答案后,这是一个可以重复使用的扩展方法,正如我在项目中所需要的那样。
public static class LinqExtensions { public static Expression> WildCardWhere(this Expression> source, Expression> selector, string terms, char separator) { if (terms == null || selector == null) return source; foreach (string term in terms.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries)) { string current = term; source = source.And( Expression.Lambda>( Expression.Call(selector.Body, "Contains", null, Expression.Constant(current)), selector.Parameters[0] ) ); } return source; } }
用法:
var terms = "%test%.doc%"; Expression> whereClause = d => d; whereClause = whereClause.WildCardWhere(d => d.docName, terms, '%'); whereClause = whereClause.WildCardWhere(d => d.someOtherProperty, "another%string%of%terms", '%'); var result = ListOfDocs.Where(whereClause).ToList();
该扩展使用了https://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/上的谓词构建器。 生成的sql对表执行单个表扫描,无论其中有多少个术语。 如果你想要iQueryable的扩展,你可以从Jo Vdb开始。
使用正则表达式……
以下将打印出当前目录中与test .doc *匹配的所有文件(dos通配符样式 – 我相信这是你要求的)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.IO; namespace RegexFileTester { class Program { static void Main(string[] args) { string[] _files = Directory.GetFiles("."); var _fileMatches = from i in _files where Regex.IsMatch(i, ".*test*.doc.*") //where Regex.IsMatch(i, ".*cs") select i; foreach(var _file in _fileMatches) { Console.WriteLine(_file); } } } }
拆分字符串
var str = "%test%.doc%"; var arr = str.Split(new[]{'%'} ,StringSplitOptions.RemoveEmptyEntries); var q = tblUsers.Select (u => u); foreach (var item in arr) { var localItem = item; q = q.Where (x => x.userName.Contains(localItem)); }
所以我尝试了同样的事情 – 尝试配对List以返回匹配SearchTerm的所有候选者。 我想要它,以便如果用户键入“亚利桑那州”它将返回所有内容,无论亚利桑那州的情况。 此外,如果用户键入“Arizona Cha”,它将返回“Arizona License Change”之类的项目。 以下工作:
上述就是C#学习教程:像LINQ to Entities中的运算符或使用通配符一样分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
private List GetCertListBySearchString() { string[] searchTerms = SearchString.Split(' '); List allCerts = _context.Certifications.ToList(); allCerts = searchTerms.Aggregate(allCerts, (current, thisSearchString) => (from ac in current where ac.Name.ToUpper().Contains(thisSearchString.ToUpper()) select ac).ToList()); return allCerts; }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1031041.html