2016-12-21 44 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

感謝大家尋找,發現問題....... 。我仔細看看代碼,你會發現當創建樣本數據時會使用兩個不同的函數。一個創建int [],另一個創建string []。改變他們都是int [],現在好了。 – gilesrpa

+0

這沒有解決問題 – gilesrpa

+0

是否有一個原因,你爲什麼使用表達式而不是使用簡單的lambda表達式來構建它? – MistyK

回答

3

的這裏的問題是,你定義兩個泛型類型屬性:TSourceTKey,但實際上你有三種人。它的工作原理,如果TKey是同一類型lowValuehighValue(均爲int),但如果lowValuehighValue是類型string和TKEY的仍然是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); 
}