Using Linq Expression.GreatThan on Strings
-
I am using to build a set of functions that will allow me to build complex queries within Linq. So far I have the following code:
private IQueryable BuildSampleEntityInt(params int\[\] values) { return values.Select( value => new SampleEntityInt() { SampleSearchKey = value }).AsQueryable(); } public static IQueryable Between(this IQueryable source, Expression\> keySelector, TKey low, TKey high, bool inclusive = true) where TKey : IComparable { 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\>( and, keySelector.Parameters); return source.Where(lambda); } private IQueryable BuildSampleEntityInt(params int\[\] values) { return values.Select( value => new SampleEntityInt() { SampleSearchKey = value }).AsQueryable(); }
If I use 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());
All is well, but if I use:
lowValueString = "3"; highValueString = "10"; var sampleData = BuildSampleEntityInt(1, 3, 10, 11, 12, 15); var query = sampleData.Between(s => s.SampleSearchKey, lowValueString , highValueString); Assert.AreEqual(2, query.Count());
The code crashes because the methods; GreaterThan, LessThan, GreaterThanOrEqual and LessThanOrEqual of an Expression does not work with Strings.
-
I am using to build a set of functions that will allow me to build complex queries within Linq. So far I have the following code:
private IQueryable BuildSampleEntityInt(params int\[\] values) { return values.Select( value => new SampleEntityInt() { SampleSearchKey = value }).AsQueryable(); } public static IQueryable Between(this IQueryable source, Expression\> keySelector, TKey low, TKey high, bool inclusive = true) where TKey : IComparable { 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\>( and, keySelector.Parameters); return source.Where(lambda); } private IQueryable BuildSampleEntityInt(params int\[\] values) { return values.Select( value => new SampleEntityInt() { SampleSearchKey = value }).AsQueryable(); }
If I use 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());
All is well, but if I use:
lowValueString = "3"; highValueString = "10"; var sampleData = BuildSampleEntityInt(1, 3, 10, 11, 12, 15); var query = sampleData.Between(s => s.SampleSearchKey, lowValueString , highValueString); Assert.AreEqual(2, query.Count());
The code crashes because the methods; GreaterThan, LessThan, GreaterThanOrEqual and LessThanOrEqual of an Expression does not work with Strings.
If you would like to implement
CompareTo()
method, check this: [IComparable.CompareTo Method (Object) (System)](https://msdn.microsoft.com/en-us/library/system.icomparable.compareto(v=vs.110).aspx).GreaterThan()
andLessThan()
methods won't work on strings. Why? It's simple. String is not numeric value! To be able to comparelowValueString
andhighValueString
with the set of numbers, you need to convert string values into proper data type. Convertion should be made before you data intoBetween
method.