I have followed several threads on SO and other websites and am still having difficulty.
I have the following code:
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);
}
If I call this function with the following code:
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());
It works. But If I use Strings instead like:
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());
or convert the strings to integers first
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());
I get the following error:
{"The binary operator GreaterThanOrEqual is not defined for the types 'System.String' and 'System.Int32'."}
When the following line runs.
var lowerBound = (inclusive)
? Expression.GreaterThanOrEqual(key, Expression.Constant(intLow, typeof(int)))
: Expression.GreaterThan(key, Expression.Constant(intLow, typeof(int)));
Can anyone point out what needs to be changed?
I have added the following:
private IQueryable<SampleEntityInt> BuildSampleEntityInt(params int[] values)
{
return values.Select(
value =>
new SampleEntityInt() { SampleSearchKey = value }).AsQueryable();
}
The problem here is that you define two generic type attributes:
TSourceandTKey, but actually you have three types of them. It works, ifTKeyis the same type aslowValueandhighValue(both areint), but it doesn't work iflowValueandhighValueare of the typestringand TKey is stillint.Code you provided works fine, if i add the third generic parameter
TLowHigh, that's a type of your low/hight arguments :