2016-12-21 8 views
1

私はSOや他のウェブサイト上のいくつかのスレッドに従っており、まだ困難を抱えています。Linq式。同等以上の文字列のため

私は、次のコードを持っている:

public static IQueryable<TSource> Between<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, TKey low, TKey high, bool inclusive = true) where TKey : IComparable<TKey> 
    { 
     var key = Expression.Invoke(keySelector, keySelector.Parameters.ToArray()); 

     var intLow = int.Parse(low.ToString()); 
     var intHigh = int.Parse(high.ToString()); 

     var lowerBound = (inclusive) 
        ? Expression.GreaterThanOrEqual(key, Expression.Constant(intLow, typeof(int))) 
        : Expression.GreaterThan(key, Expression.Constant(intLow, typeof(int))); 

     var upperBound = (inclusive) 
        ? Expression.LessThanOrEqual(key, Expression.Constant(intHigh, typeof(int))) 
        : Expression.LessThan(key, Expression.Constant(intHigh, typeof(int))); 

     var and = Expression.AndAlso(lowerBound, upperBound); 
     var lambda = Expression.Lambda<Func<TSource, bool>>(
         and, keySelector.Parameters); 

     return source.Where(lambda); 
    } 

私は次のコードでこの関数を呼び出す場合:

lowValue = 2; 
highValue = 11; 

var sampleData = BuildSampleEntityInt(1, 3, 10, 11, 12, 15); 
var query = sampleData.Between(s => s.SampleSearchKey, lowValue, highValue, false); 
Assert.AreEqual(2, query.Count()); 

それが動作します。しかし、私は代わりのような文字列を使用する場合:

lowValueString = "3"; 
highValueString = "10"; 

var sampleData = BuildSampleEntityString(1, 3, 10, 11, 12, 15); 
var query = sampleData.Between(s => s.SampleSearchKey, lowValueString , highValueString); 
Assert.AreEqual(2, query.Count()); 

または

lowValueString = "3"; 
highValueString = "10"; 
int.TryParse(lowValueString, out lowValue); 
int.TryParse(highValueString, out highValue); 


var sampleData = BuildSampleEntityString(1, 3, 10, 11, 12, 15); 
var query = sampleData.Between(s => s.SampleSearchKey, lowValue, highValue); 
Assert.AreEqual(2, query.Count()); 

私は次のエラーを取得最初の整数に文字列を変換:

{"The binary operator GreaterThanOrEqual is not defined for the types 'System.String' and 'System.Int32'."}

次の行が実行されます。

var lowerBound = (inclusive) 
      ? Expression.GreaterThanOrEqual(key, Expression.Constant(intLow, typeof(int))) 
      : Expression.GreaterThan(key, Expression.Constant(intLow, typeof(int))); 

変更する必要があるものは誰でも指摘できますか?

私は次のように追加しました:

private IQueryable<SampleEntityInt> BuildSampleEntityInt(params int[] values) 
    { 
     return values.Select(
       value => 
       new SampleEntityInt() { SampleSearchKey = value }).AsQueryable(); 
    } 
+0

おかげで、問題を発見した.......あなたがサンプルデータを作成したときに2つの異なる関数が使用されていることに気づくでしょう。一方はint []を作成し、他方はstring []を作成します。それらを両方ともint []に変更しました。 – gilesrpa

+0

これは問題を解決しませんでした – gilesrpa

+0

単純なラムダを使用するのではなく、式でビルドする理由はありますか? – MistyK

答えて

3

ここでの問題は、次の2つの一般的なタイプの属性を定義することです:TSourceTKeyを、実際にあなたがそれら3つのタイプがあります。 TKeylowValuehighValue(両方ともintある)と同じ型である場合は、動作しますが、lowValuehighValueはタイプstringのものであり、処理鍵はまだintであれば、それは動作しません。あなたは罰金作品を提供

コード、私は第三ジェネリックパラメータTLowHighを追加する場合、それはあなたの低い/ Hightの引数のタイプです:誰もが見ているため

public static IQueryable<TSource> Between<TSource, TKey, TLowHigh>(
     this IQueryable<TSource> source, 
     Expression<Func<TSource, TKey>> keySelector, 
     TLowHigh low, 
     TLowHigh high, 
     bool inclusive = true) 
      where TKey : IComparable<TKey> 
{ 
    var key = Expression.Invoke(keySelector, keySelector.Parameters.ToArray()); 

    var intLow = int.Parse(low.ToString()); 
    var intHigh = int.Parse(high.ToString()); 

    var lowerBound = (inclusive) 
      ? Expression.GreaterThanOrEqual(key, Expression.Constant(intLow, typeof(int))) 
      : Expression.GreaterThan(key, Expression.Constant(intLow, typeof(int))); 

    var upperBound = (inclusive) 
      ? Expression.LessThanOrEqual(key, Expression.Constant(intHigh, typeof(int))) 
      : Expression.LessThan(key, Expression.Constant(intHigh, typeof(int))); 

    var and = Expression.AndAlso(lowerBound, upperBound); 
    var lambda = Expression.Lambda<Func<TSource, bool>>(
        and, keySelector.Parameters); 

    return source.Where(lambda); 
} 
関連する問題