대신 Expression<Func<T, bool>>
의 LambdaExpression
을 가지고 있고 Where
로 사용하고 싶지만 IQueryable
(이 DbSet
클래스가 구현)에 오히려 IQueryable<T>
이상을.
여러분이 알아야 할 것은 IQueryable<T>
확장 메서드가 쿼리 식 트리의 메서드에 MethodCallExpression
메서드를 내보내는 것입니다.
예를 들어, IQueryable
에 Where
또는 Select
는 다음과 같은 사용자 정의 확장 방법을 사용할 수 있습니다 에뮬레이션 :
이
public static class QueryableExtensions
{
public static IQueryable Where(this IQueryable source, LambdaExpression predicate)
{
var expression = Expression.Call(
typeof(Queryable), "Where",
new Type[] { source.ElementType },
source.Expression, Expression.Quote(predicate));
return source.Provider.CreateQuery(expression);
}
public static IQueryable Select(this IQueryable source, LambdaExpression selector)
{
var expression = Expression.Call(
typeof(Queryable), "Select",
new Type[] { source.ElementType, selector.Body.Type },
source.Expression, Expression.Quote(selector));
return source.Provider.CreateQuery(expression);
}
}
당신이 필요한 다른 Queryable
방법에 대한 유사 할 수 있습니다.
업데이트 : 당신이 재미 있기 때문에가 여기에 제네릭 메서드 정의를 얻고 그것에서 일반적인 방법을 구축하는 식 프로토 타입을 사용하는 예제입니다
public static class QueryableExtensions
{
static MethodInfo QueryableMethod<T>(this Expression<Func<IQueryable<object>, T>> prototype, params Type[] types)
{
return ((MethodCallExpression)prototype.Body).Method
.GetGenericMethodDefinition()
.MakeGenericMethod(types);
}
public static IQueryable Where(this IQueryable source, LambdaExpression predicate)
{
var expression = Expression.Call(
QueryableMethod(q => q.Where(x => true), source.ElementType),
source.Expression, Expression.Quote(predicate));
return source.Provider.CreateQuery(expression);
}
public static IQueryable Select(this IQueryable source, LambdaExpression selector)
{
var expression = Expression.Call(
QueryableMethod(q => q.Select(x => 1), source.ElementType, selector.Body.Type),
source.Expression, Expression.Quote(selector));
return source.Provider.CreateQuery(expression);
}
}
당신이 '표현을 만들려면 어떻게해야합니까 >''T '를 모른다면? –
@IvanStoev 유형을 사용하여 표현식을 만들 수 있습니다. – oscilatingcretin
'LambdaExpression'을 반환하는 비 generic'Expression.Lambda'와 비슷합니까? 그리고 그것을 'Where'에 바인딩하고 싶습니까? –