2009-07-27 4 views
1

저는 linq을 처음 사용하고 IQueryable을 확장하여 좀 더 깊게 파고 들기를 원했습니다. 날짜 범위를 쿼리하는 간단한 확장 메서드를 만들고 싶습니다. 다음에 해당하는 것 :IQueryable 확장 및 속성 구문 분석

IQuerable.Where(x => x.Date > fromDate && x.Date < toDate); 

그러나 날짜에 약간의 처리가 추가됩니다. 나는 메서드 호출 뭔가처럼 있도록 쿼리를 수행하는 속성을 구문 분석 할 수 있도록하려면 :

IQueryable.WhereDateRange(x => x.Date, fromDate, toDate); 
IQueryable.WhereDateRange(x => x.AnotherDate, fromDate, toDate); 

내가 다음과 같은 뭔가 찾고 있었어요하지만 난 내가 뭘하는지 전혀 모르겠어요

public static IQueryable<T> WhereDateRange<T>(this IQueryable<T> source, Func<T, DateTime> getter, DateTime from, DateTime to) { 
//query here 
} 

가능하면 어떻게 할 수 있습니까?

답변

4

테스트되지 않은 :하지만, 정보에 대한

public static IQueryable<T> WhereDateRange<T>(
    this IQueryable<T> source, Expression<Func<T, DateTime>> getter, 
    DateTime from, DateTime to) 
{ 
    Expression body = getter.Body; 

    var predicate = Expression.Lambda<Func<T, bool>>(
     Expression.And(
      Expression.GreaterThan(body, Expression.Constant(from)), 
      Expression.LessThan(body, Expression.Constant(to)) 
     ), 
     getter.Parameters); 
    return source.Where(predicate); 
} 

하지만; 보통 범위는 >= start< end이라고 가정하므로 Expression.GreaterThanOrEqual을 사용합니다.

public static IQueryable<T> WhereInRange<T, TValue>(
    this IQueryable<T> source, Expression<Func<T, TValue>> selector, 
    TValue from, TValue to) 
{ 
    Expression body = selector.Body; 

    var predicate = Expression.Lambda<Func<T, bool>>(
     Expression.And(
      Expression.GreaterThanOrEqual(
       body, Expression.Constant(from, typeof(TValue))), 
      Expression.LessThan(
       body, Expression.Constant(to, typeof(TValue))) 
     ), 
     selector.Parameters); 
    return source.Where(predicate); 
} 

(이 경우에 상수에 TValue를 지정해야 null 때문에 그렇지 않으면 큰 문제를 일으킬 수)

자세한 재사용 (내가 여기 GreaterThanOrEqual를 사용하고 있고 주목할) 것을 만드는

+0

또 다른 참고 사항 : 이것은 외부의 가장 IQueryable에서만 작동합니다.이 쿼리를 linq에서 SQL 또는 엔터티 프레임 워크로 사용하면 공급자가이 메서드를 변환하는 방법을 모르기 때문에 실패합니다. 당신은이 일을 위해 좀 더 애교있는 트릭을해야한다 –

+0

@Roger 질의 문법으로 할 수있는 것은 수동으로도 할 수있다. 궁극적으로는 –

+0

은 select, where 또는 wrapping 같은 다른 모든 메소드를 대체하지 않고 서브 쿼리에서 위의 메소드를 실제로 지원할 수 있는가? IQueryable? –