2017-09-06 22 views
4

그래서 같은 쿼리를 반복해서 다시 작성하는 것에 다소 지쳐 가고 있습니다.IsInDateTimeRange로 IQueryable 확장하기

repo.Query().Where(stuff => stuff.Timestamp >= minTime && stuff.Timestamp <= maxTime && ...); 

나는 내가 대한 그러나, 단지 Func<T, DateTime>DateTimeIsInDateTimeRange라는 방법 IQueryable을 확장하고, IEnumerable 매우 쉬울 것이다이

repo.Query().IsInDateTimeRange(stuff => stuff.Timestamp, minTime, maxTime) ... 

같이 사용한다고 생각 IQueryable 나는 Expression을 가져갈 필요가 있으며 이것을 어떻게 사용하는지 잘 모르겠습니다.

이것은 시도했지만 작동하지 않는 것 같습니다.

public static IQueryable<TValue> IsInDateTimeRange<TValue>(
     this IQueryable<TValue> self, 
     Expression<Func<TValue, DateTime>> getMember, 
     DateTime minTime, 
     DateTime maxTime) 
    { 
     return self.Where(value => minTime >= getMember(value) && maxTime <= getMember(value)); 
    } 
+1

무슨 뜻인지 설명해주십시오. 예외? 컴파일 오류입니까? –

+1

대부분의 Linq 제공 업체는 'getMember (value)'노이즈로 인해 변환 된 표현식을 상점 쿼리로 변환 할 수 없습니다. 관련 부분을 보통의'Expression.Property' 접근 자로 수동으로 대체해야합니다. – haim770

+0

예, 컴파일러 오류입니다. 그것은 델리게이트가 아니므로 getMember를 호출 할 수 없습니다. – jool

답변

7

수동 방법에 전달되는 속성 액세스 식에 따라 표현을 구축하여이 작업을 수행 할 수 있습니다 : 당신이 작동하지 않는 말할 때

public static IQueryable<TValue> IsInDateTimeRange<TValue>(
    this IQueryable<TValue> self, 
    Expression<Func<TValue, DateTime>> getMember, 
    DateTime minTime, 
    DateTime maxTime) 
{ 
    var getMemberBody = getMember.Body; 
    var filter = Expression.Lambda<Func<TValue, bool>>(
     Expression.And(
      Expression.LessThanOrEqual(
       Expression.Constant(minTime), 
       getMemberBody 
      ), 
      Expression.LessThanOrEqual(
       getMemberBody, 
       Expression.Constant(maxTime) 
      ) 
     ), 
     getMember.Parameters 
    ); 
    return self.Where(filter); 
} 
+0

나를 이길. 내가 할 수있는 일은 단지'getMember.Parameters.First()'를 취할 필요가 없다는 것입니다. 'getMembers.Parameters'를'Lambda <>()'의 두 번째 인수로 전달할 수 있어야합니다. 또한 첫 번째'LessThanOrEqual'은'GreaterThanOrEqual'이어야합니다 :). –

+0

@MikeStrobel 당신이 맞아요, 그렇게 편집했습니다 : –

+0

(<='를 두 번 사용했습니다) 당신을위한 부 논리 오류가 수정되었습니다. –