Entity framework &引用;例如;实体框架中的查询

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

如何使用edo实体框架在ASP.net MVC中获得通配符文本搜索(如SQL的“like”语句)

我认为这会起作用:

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();
}