의 결과를 사용하려는 경우에서 Entity Framework 또는 LINQ2SQL을 사용하는 경우 selector
은 기본 LINQ 공급자가 엔터티 명령 텍스트를 작성하는 동안 대리자를 인식하지 않으므로 대리자 대신 표현식이어야합니다.
따라서, 당신은 다음과 같이 표현 스스로 뭔가를 구축해야 :
비슷한 유형 :
enum SearchStrategy
{
Contains,
StartsWith,
EndsWith,
Equals
}
class SearchItem
{
public SearchStrategy SearchStrategy { get; set; }
public string Value { get; set; }
}
다음은 필터링 표현식을 빌드 코드가있어 가지고, 가정
(:
를
static class QueryBuilder
{
private static readonly Lazy<MethodInfo> toLowerMethodInfo;
private static readonly Dictionary<SearchStrategy, Lazy<MethodInfo>> searchStrategyToMethodInfoMap;
static QueryBuilder()
{
toLowerMethodInfo = new Lazy<MethodInfo>(() => typeof(string).GetMethod("ToLower", new Type[0]));
searchStrategyToMethodInfoMap = new Dictionary<SearchStrategy, Lazy<MethodInfo>>
{
{
SearchStrategy.Contains,
new Lazy<MethodInfo>(() => typeof(string).GetMethod("Contains", new[] { typeof(string) }))
},
{
SearchStrategy.StartsWith,
new Lazy<MethodInfo>(() => typeof(string).GetMethod("StartsWith", new[] { typeof(string) }))
},
{
SearchStrategy.EndsWith,
new Lazy<MethodInfo>(() => typeof(string).GetMethod("EndsWith", new[] { typeof(string) }))
},
{
SearchStrategy.Equals,
new Lazy<MethodInfo>(() => typeof(string).GetMethod("Equals", new[] { typeof(string) }))
},
};
}
public static Expression<Func<T, bool>> MatchMyModelFieldByStrategy<T>(SearchItem searchItem, Expression<Func<T, string>> selector)
{
// "doe"
var searchItemKey = searchItem.Value.ToLower();
// _.Name.ToLower()
var toLowerCallExpr = Expression.Call(selector.Body, toLowerMethodInfo.Value);
// a method we shall use for searching
var searchMethodInfo = searchStrategyToMethodInfoMap[searchItem.SearchStrategy].Value;
// _ => _.Name.ToLower().SomeSearchMethod("doe")
return Expression.Lambda<Func<T, bool>>(
Expression.Call(toLowerCallExpr, searchMethodInfo, Expression.Constant(searchItemKey)),
selector.Parameters);
}
}
모든 MatchMyModelFieldByStrategy
전화에 대해 동일한 결과를 얻을 수 있기 때문에 반영 결과를 캐시하는 데 약간의 게으름을 추가했습니다.
지금 테스트 개체 유형 :
class MyEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
...와 샘플 코드 : 그런데
static void Main(string[] args)
{
Console.WriteLine(QueryBuilder.MatchMyModelFieldByStrategy<MyEntity>(
new SearchItem { SearchStrategy = SearchStrategy.Contains, Value = "doe" }, _ => _.Name));
Console.WriteLine(QueryBuilder.MatchMyModelFieldByStrategy<MyEntity>(
new SearchItem { SearchStrategy = SearchStrategy.StartsWith, Value = "doe" }, _ => _.Name));
Console.WriteLine(QueryBuilder.MatchMyModelFieldByStrategy<MyEntity>(
new SearchItem { SearchStrategy = SearchStrategy.EndsWith, Value = "doe" }, _ => _.Name));
Console.WriteLine(QueryBuilder.MatchMyModelFieldByStrategy<MyEntity>(
new SearchItem { SearchStrategy = SearchStrategy.Equals, Value = "doe" }, _ => _.Name));
Console.ReadLine();
}
는 상부 케이스 문자열 검색 및 .NET의 비교에 적합하다. – Ivan
Entity Framework 또는 LINQ2SQL에서 'MatchMyModelFieldByStrategy'의 결과를 사용할 계획입니까? 그렇다면 배치 된 응답의 코드로 인해 실행시 엔티티 명령 컴파일 예외가 발생하게됩니다. 이는 기본 LINQ 공급자가'selector '를 인식하지 못하기 때문입니다. – Dennis
@Dennis yep 동적 쿼리 빌더를 만들기 위해 필요합니다 ... EF와 함께 사용할 유효한 대안을 알고 있습니까? –