【问题标题】:Linq Expressions. Equivalent of greater than for stringsLinq 表达式。等价于大于字符串
【发布时间】:2016-12-21 14:53:04
【问题描述】:

我在 SO 和其他网站上关注了几个主题,但仍然遇到困难。

我有以下代码:

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());

我收到以下错误:

{"没有为类型定义二元运算符GreaterThanOrEqual 'System.String' 和 '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();
    }

【问题讨论】:

  • 感谢大家的关注,发现问题........我仔细查看代码,您会注意到创建示例数据时使用了两个不同的函数。一个创建 int[] 而另一个创建 string[]。将它们都更改为 int[],现在可以了。
  • 这并没有解决问题
  • 你用表达式而不是简单的 lambdas 来构建它有什么原因吗?
  • 等等...您的数据是数字...为什么您需要能够将数字与字符串进行比较?

标签: c# linq lambda expression linq-expressions


【解决方案1】:

这里的问题是你定义了两个泛型类型属性:TSourceTKey,但实际上你有它们的三种类型。如果TKeylowValuehighValue 的类型相同(两者都是int),则它可以工作,但如果lowValuehighValue 的类型为string 和TKey,则它不起作用仍然是int

您提供的代码可以正常工作,如果我添加第三个通用参数TLowHigh,那是您的低/高参数类型:

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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 2014-11-08
    • 2012-08-16
    • 2012-01-07
    相关资源
    最近更新 更多