2017-09-06 9 views
4

だから、同じクエリを何度も何度も書き直すことに多少疲れています。IsInDateTimeRangeでIQueryableを拡張する

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

私はこれがしかしのために、ちょうどFunc<T, DateTime>と2 DateTime秒、IEnumerableのために非常に簡単だろうIsInDateTimeRangeと呼ばれる方法でIQueryableを拡張し、この

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 <>() 'の2番目の引数として渡すことができます。また、最初の 'LessThanOrEqual'は' GreaterThanOrEqual'でなければなりません。 –

+0

@MikeStrobelあなたは正しく編集されました。 –

+0

あなたはマイナーなロジックエラーを修正しました( '<='を2回使用しました)。 –

関連する問題