使用正则表达式搜索时的通配符 (*,!)
Wildcard (*,!) on search using Regex
我是 MVC 新手,我想在数据库上执行通配符 (*, !) 搜索。这是我使用 Regex 所做的:
控制器:
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
CrossWord_dbEntities db = new CrossWord_dbEntities();
public ActionResult Index(string searching)
{
var regEx = WildcardToRegex(searching);
return View(db.tbl_values.Where(x => Regex.IsMatch(x.Name, regEx, RegexOptions.Singleline)));//.ToList()));
}
public static string WildcardToRegex(string pattern)
{
return "^" + Regex.Escape(pattern).
Replace("\*", ".*").
Replace("\?", ".") + "$";
}
}
}
查看:
@model IEnumerable<WebApplication1.Models.tbl_values>
<br /><br />
@using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
@Html.TextBox("searching") <input type="submit" value="Search" />
}
<table class="table table-striped">
<thead>
<tr>
<th>Results</th>
</tr>
</thead>
<tbody>
@if (Model.Count() == 0)
{
<tr>
<td colspan="3" style="color:red">
No Result
</td>
</tr>
}
else
{
foreach (var item in Model)
{
<tr>
<td>
@item.Name
</td>
</tr>
}
}
</tbody>
</table>
使用上面的代码,当我 运行 我在行中得到一个异常:“@if (Model.Count() == 0)”
LINQ to Entities 无法识别方法 'Boolean IsMatch(System.String, System.String, System.Text.RegularExpressions.RegexOptions)' 方法,并且无法将此方法转换为存储表达式。
我需要做什么来解决这个问题?
我尝试在控制器的 return 行中添加 "ToList()"
return View(db.tbl_values.Where(x => Regex.IsMatch(x.Name, regEx, RegexOptions.Singleline).ToList()));
但我在这一行得到了相同的期望。
谢谢阿米尔
异常消息很简单:在 LINQ to Entities 模式下执行查询时,Regex.IsMatch()
方法没有等效的 SQL 语句。您需要在 Where
子句之前放置 AsEnumerable()
或 ToList()
方法以将 DbContext
实体具体化为 IEnumerable
对象:
public class HomeController : Controller
{
CrossWord_dbEntities db = new CrossWord_dbEntities();
public ActionResult Index(string searching)
{
var regEx = WildcardToRegex(searching);
return View(db.tbl_values.AsEnumerable().Where(x => Regex.IsMatch(x.Name, regEx, RegexOptions.Singleline)));
}
}
由于您的 WildcardToRegex
方法仅适用于 IEnumerable
或 LINQ to Objects,您可以尝试添加 this solution 中描述的其他方法以与 IQueryable
一起使用实体如下:
public static IQueryable<TSource> WhereLike<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, string>> valueSelector, string value, char wildcard)
{
return source.Where(BuildLikeExpression(valueSelector, value, wildcard));
}
private static Expression<Func<TElement, bool>> BuildLikeExpression<TElement>(Expression<Func<TElement, string>> 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<Func<TElement, bool>>(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 });
}
然后对任何实施 IQueryable
的实体使用 WhereLike
方法,如下例所示:
// usage example
using (CrossWord_dbEntities db = new CrossWord_dbEntities())
{
var query = db.tbl_values.WhereLike(x => x.Name, "[search text]", "[wildcard character]");
}
类似问题:
linq to entities doesn't recognize a method
我是 MVC 新手,我想在数据库上执行通配符 (*, !) 搜索。这是我使用 Regex 所做的:
控制器:
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
CrossWord_dbEntities db = new CrossWord_dbEntities();
public ActionResult Index(string searching)
{
var regEx = WildcardToRegex(searching);
return View(db.tbl_values.Where(x => Regex.IsMatch(x.Name, regEx, RegexOptions.Singleline)));//.ToList()));
}
public static string WildcardToRegex(string pattern)
{
return "^" + Regex.Escape(pattern).
Replace("\*", ".*").
Replace("\?", ".") + "$";
}
}
}
查看:
@model IEnumerable<WebApplication1.Models.tbl_values>
<br /><br />
@using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
@Html.TextBox("searching") <input type="submit" value="Search" />
}
<table class="table table-striped">
<thead>
<tr>
<th>Results</th>
</tr>
</thead>
<tbody>
@if (Model.Count() == 0)
{
<tr>
<td colspan="3" style="color:red">
No Result
</td>
</tr>
}
else
{
foreach (var item in Model)
{
<tr>
<td>
@item.Name
</td>
</tr>
}
}
</tbody>
</table>
使用上面的代码,当我 运行 我在行中得到一个异常:“@if (Model.Count() == 0)”
LINQ to Entities 无法识别方法 'Boolean IsMatch(System.String, System.String, System.Text.RegularExpressions.RegexOptions)' 方法,并且无法将此方法转换为存储表达式。
我需要做什么来解决这个问题?
我尝试在控制器的 return 行中添加 "ToList()"
return View(db.tbl_values.Where(x => Regex.IsMatch(x.Name, regEx, RegexOptions.Singleline).ToList()));
但我在这一行得到了相同的期望。
谢谢阿米尔
异常消息很简单:在 LINQ to Entities 模式下执行查询时,Regex.IsMatch()
方法没有等效的 SQL 语句。您需要在 Where
子句之前放置 AsEnumerable()
或 ToList()
方法以将 DbContext
实体具体化为 IEnumerable
对象:
public class HomeController : Controller
{
CrossWord_dbEntities db = new CrossWord_dbEntities();
public ActionResult Index(string searching)
{
var regEx = WildcardToRegex(searching);
return View(db.tbl_values.AsEnumerable().Where(x => Regex.IsMatch(x.Name, regEx, RegexOptions.Singleline)));
}
}
由于您的 WildcardToRegex
方法仅适用于 IEnumerable
或 LINQ to Objects,您可以尝试添加 this solution 中描述的其他方法以与 IQueryable
一起使用实体如下:
public static IQueryable<TSource> WhereLike<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, string>> valueSelector, string value, char wildcard)
{
return source.Where(BuildLikeExpression(valueSelector, value, wildcard));
}
private static Expression<Func<TElement, bool>> BuildLikeExpression<TElement>(Expression<Func<TElement, string>> 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<Func<TElement, bool>>(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 });
}
然后对任何实施 IQueryable
的实体使用 WhereLike
方法,如下例所示:
// usage example
using (CrossWord_dbEntities db = new CrossWord_dbEntities())
{
var query = db.tbl_values.WhereLike(x => x.Name, "[search text]", "[wildcard character]");
}
类似问题:
linq to entities doesn't recognize a method