2010-03-30 9 views
3

edo 엔티티 프레임 워크를 사용하여 ASP.net MVC에서 와일드 카드 텍스트 검색 (예 : SQL의 "like"문)을 얻으려면 어떻게해야합니까?Entity Framework의 "like"쿼리

var elig = (from e in _documentDataModel.Protocol_Eligibility_View 
      where e.criteria.Contains(query) 
      select e); 

을하지만 데이터베이스에 확실히의 쿼리 문자열을 검색 할 때조차 아무런 결과도 반환하지 않는다 :

나는이 일을 할 생각했습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

답변

5

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); 
+0

더 밀접하게 내 문제를보고하면, 그것은 보인다. – sslepian

3

System.Data.Linq.SqlClient 네임 스페이스에는 SqlMethods 클래스가 포함되어 있습니다.

var elig = from e in _documentDataModel.Protocol_Eligibility_View 
      where SqlMethods.Like(e.criteria, query) 
      select e; 
2

Linq에 SqlMethods 방법을 지원하지 않는 개체에 있지만 대신 문자열 기능을 사용할 수 있습니다 :

.Where(entity => entity.Name.Contains("xyz")) 

.Where(entity => entity.Name.EndsWith("xyz")) 

.Where(entity => entity.Name.StartsWith("xyz")) 
5

이 남자는 "아주 좋은했다 WhereLike 당신은이 같은 방법처럼 사용할 수 있습니다 "와일드 카드 문자를 허용하고 와일드 카드 위치에서 파생 된 일반 메소드로 두 값 (표현식에서 오는 값 중 하나)을 비교하는 Linq의 확장입니다.

  • 의 X % -> startswith
  • 퍼센트 X -> endswith
  • 퍼센트의 X %의은 ->

http://trentacular.com/2010/08/linq-to-entities-wild-card-like-extension-method/

편집을 포함 기사는 아래로 보인다. 아래 확장 코드를 붙여 넣을 것입니다 :

+0

불행히도,이 링크는 답변에서 제공된 링크가 작동하지 않습니다. 코드를 제공해 주셔서 감사합니다. – Pac0

+0

확장 방법은 어떻게 사용합니까? – Velkumar

+0

IQueryable 또는 IEnumerable에서 다음과 같이 호출합니다. IQueryableVar.WhereLike (item => item.property, textbox.Text, '*'); textbox.Text는 여러분이 속성을 좋아할만한 것에 대한 예제입니다. –

2

Jon Koeter가 더 이상 존재하지 않는 다른 대답으로 블로그 게시물에서 올린 코드를 사용하기 시작했습니다.

그러나 실제로는 제대로 작동하지 않는 것으로 나타났습니다. 특히 IEnumerable을 사용할 때 특히 그렇습니다. 즉, ToArray을 사용하여 열거 형을 해결하고 내장 함수가 아닌 일치하는 정규식을 사용했습니다.

필자는 일단 필터링을 마친 후에 IEnumerable을 해결하기를 원했기 때문에 IQueryable으로 변환 한 다음 나머지 코드를 사용하여 올바른 Entity Framework 메서드를 찾고 호출합니다. 이렇게하면 쿼리 자체는 나중에 데이터베이스에 대해 호출되지 않으므로 정규식을 사용하지 않아도됩니다.

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

사용법 : 내 문제가 아니라 .contains 문에, 다른 곳처럼

// 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 
+0

필자는이 기사가 IQueryable에 대한 코드만을 가지고 있었으며 그것이 이상하게 작동한다고 생각합니다. 나는 IEnumerable 코드를 직접 추가했는데 (기억하지 못하는 다른 웹 사이트에서 가져온 것일 수도있다.) 나는 여러분과 함께 공유 할 수도 있다고 생각했다. –