Entity framework &引用;例如;实体框架中的查询
如何使用edo实体框架在ASP.net MVC中获得通配符文本搜索(如SQL的“like”语句) 我认为这会起作用:Entity framework &引用;例如;实体框架中的查询,entity-framework,wildcard,Entity Framework,Wildcard,如何使用edo实体框架在ASP.net MVC中获得通配符文本搜索(如SQL的“like”语句) 我认为这会起作用: var elig = (from e in _documentDataModel.Protocol_Eligibility_View where e.criteria.Contains(query) select e); 但即使在搜索数据库中肯定存在的查询字符串时,它也不会返回任何结果。我做错了什么?String.Contains
var elig = (from e in _documentDataModel.Protocol_Eligibility_View
where e.criteria.Contains(query)
select e);
但即使在搜索数据库中肯定存在的查询字符串时,它也不会返回任何结果。我做错了什么?String.Contains应该可以正常工作。SQL的LIKE语句通常通过String.StartsWith、String.Contains或String.EndsWith处理 但是,您可能有套管问题。你可以试试:
var elig = (from e in _documentDataModel.Protocol_Eligibility_View
where e.criteria.ToLower().Contains(query.ToLower())
select e);
System.Data.Linq.SqlClient命名空间包含SqlMethods类。您可以使用如下类似的方法:
var elig = from e in _documentDataModel.Protocol_Eligibility_View
where SqlMethods.Like(e.criteria, query)
select e;
Linq to entities不支持SqlMethods方法,但您可以改用字符串函数:
.Where(entity => entity.Name.Contains("xyz"))
.Where(entity => entity.Name.EndsWith("xyz"))
.Where(entity => entity.Name.StartsWith("xyz"))
这家伙为Linq做了一个非常好的“WhereLike”扩展,它接受任何通配符,并将两个值(其中一个来自表达式)与从通配符位置派生的通用方法进行比较
- x%->startswith
- %x->endswith
- %x%->包含
public static class LinqHelper
{
//Support IQueryable (Linq to Entities)
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));
}
//Support IEnumerable (Linq to objects)
public static IEnumerable<TSource> WhereLike<TSource>(this IEnumerable<TSource> sequence, Func<TSource, string> 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<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 });
}
}
}
公共静态类LinqHelper
{
//支持IQueryable(Linq到实体)
公共静态IQueryable WhereLike(此IQueryable源、表达式值选择器、字符串值、字符通配符)
{
返回source.Where(BuildLikeExpression(valueSelector,value,通配符));
}
//支持IEnumerable(Linq到对象)
公共静态IEnumerable WhereLike(此IEnumerable序列、Func表达式、字符串值、字符通配符)
{
var regEx=通配符toregex(值,通配符);
//防止多重枚举:
var arraySequence=作为TSource[]的序列?sequence.ToArray();
尝试
{
返回arraySequence.Where(item=>Regex.IsMatch(表达式(item),Regex));
}
捕获(异常)
{
返回序列;
}
}
//用于IEnumerable支持
私有静态字符串通配符toregex(字符串值,字符通配符)
{
返回“(?i:^”+Regex.Escape(value).Replace(“\\”+通配符,“.”+通配符)+“$”;
}
//用于可更换支架
私有静态表达式BuildLikeExpression(表达式值选择器、字符串值、字符通配符)
{
如果(valueSelector==null)抛出新的ArgumentNullException(“valueSelector”);
var方法=GetLikeMethod(值,通配符);
value=value.Trim(通配符);
var body=Expression.Call(valueSelector.body,方法,Expression.Constant(value));
var parameter=valueSelector.Parameters.Single();
返回表达式.Lambda(主体,参数);
}
私有静态MethodInfo GetLikeMethod(字符串值,字符通配符)
{
var methodName=“等于”;
var textLength=value.Length;
value=value.TrimEnd(通配符);
如果(textLength>value.Length)
{
methodName=“StartsWith”;
textLength=value.Length;
}
value=value.TrimStart(通配符);
如果(textLength>value.Length)
{
methodName=(methodName=“StartWith”)?“包含”:“EndsWith”;
}
var stringType=typeof(字符串);
返回stringType.GetMethod(methodName,new[]{stringType});
}
}
}
我开始使用Jon Koeter在另一个答案中发布的代码,这个答案似乎已经不存在了
然而,我发现它并没有真正正常工作,尤其是在使用IEnumerable
时。也就是说,它使用ToArray
解析可枚举项,并使用正则表达式进行匹配,而不是使用内置函数
因为我只想在完成筛选后解析我的IEnumerable
,所以我做了一些更改,将其转换为IQueryable
,然后使用代码的其余部分找到正确的实体框架方法并调用它。这样,查询本身直到稍后才会针对数据库调用,并且避免了使用正则表达式
public static IQueryable<T> WhereLike<T>(this IQueryable<T> source, Expression<Func<T, string>> valueSelector, string value, char wildcard)
{
return source.Where(BuildLikeExpression(valueSelector, value, wildcard));
}
public static IEnumerable<T> WhereLike<T>(this IEnumerable<T> source, Expression<Func<T, string>> valueSelector, string value, char wildcard)
{
return source.AsQueryable().WhereLike(valueSelector, value, wildcard);
}
private static Expression<Func<T, bool>> BuildLikeExpression<T>(Expression<Func<T, 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<T, 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(此IQueryable源、表达式值选择器、字符串值、字符通配符)
{
返回source.Where(BuildLikeExpression(valueSelector,value,通配符));
}
公共静态IEnumerable WhereLike(此IEnumerable源、表达式值选择器、字符串值、字符通配符)
{
返回source.AsQueryable().WhereLike(valueSelector、value、通配符);
}
私有静态表达式BuildLikeExpression(表达式值选择器、字符串值、字符通配符)
{
如果(valueSelector==null)抛出新的ArgumentNullException(“valueSelector”);
var方法=GetLikeMethod(值,通配符);
value=value.Trim(通配符);
var body=Expression.Call(valueSelector.body,方法,Expression.Constant(value));
var parameter=valueSelector.Parameters.Single();
返回表达式.Lambda(主体,参数);
}
私有静态MethodInfo GetLikeMethod(字符串值,字符通配符)
{
var methodName=“等于”;
var textLength=value.Length;
value=value.TrimEnd(通配符);
如果(textLength>value.Length)
{
methodName=“StartsWith”;
textLength=value.Length;
}
value=value.TrimStart(通配符);
如果(textLength>value.Length)
{
methodName=(methodName=“StartWith”)?“包含”:“EndsWith”;
}
var stringType=typeof(字符串);
返回stringType.GetMethod(methodName,new[]{stringType});
}
用法:
// example data set
var data = new List<Person> {
new Person{FirstName="John", LastName="Smith"},
new Person{FirstName="Jane", LastName="Doe"}
};
data.WhereLike(x=>x.FirstName, "John", "%"); // returns John Smith
data.WhereLike(x=>x.FirstName, "J%", "%"); // returns John Smith and Jane Smith
//示例数据集
var数据=新列表{
新人{FirstName=“John”,LastName=“Smith”},
新人{FirstName=“Jane”,LastName=“Doe”}
};
data.WhereLike(x=>x.FirstName,“John”,“%
try
{
using (var db = new YOUREntities())
{
var data = db.LenderProgram.Where(i => DbFunctions.Like(i.LenderProgramCode, "OTO%"))
.ToList();
return data;
}
}
catch (Exception e)
{
e.HandleException();
}