加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 是否可以为字符串实现ExpressionTree.GreaterThan等,以便L

发布时间:2020-12-15 21:47:32 所属栏目:百科 来源:网络整理
导读:我今天早上( Query my model on a range of values)看到了一个似乎由( https://stackoverflow.com/a/1447926/195550)回答的问题,但是那里的整个情况让我对更广泛的解决方案感兴趣. 我希望能够使用Jon Skeet的答案来实现在非SQL生成的环境中使用字符串键的Bet
我今天早上( Query my model on a range of values)看到了一个似乎由( https://stackoverflow.com/a/1447926/195550)回答的问题,但是那里的整个情况让我对更广泛的解决方案感兴趣.

我希望能够使用Jon Skeet的答案来实现在非SQL生成的环境中使用字符串键的Betweent,但看起来字符串没有实现GreaterThan,LessThan,GreaterThanOrEqual,LessThanOrEqual运算符的事实进入Linq能够构建执行此操作所必需的表达式树的方式.

>我意识到可以使用CompareTo方法进行查询来完成此任务,但我真的很喜欢查询的优雅.Between(v => v.StringKey,“abc”,“hjk”)表达式.
>我查看了System.Linq.Expression程序集,看到它正在寻找名为’op_GreaterThan’的方法,例如对于GreaterThan操作,但我不知道

>我是否可以为字符串实现此功能(知道我无法为字符串扩展实际的’>’运算符)
>如何构建正确的方法签名.

>我创建了以下示例和测试,显示了Between扩展方法对字符串键不起作用的位置.

如果可以为字符串键实现它将是非常优雅的.有人对如何做到这一点有任何建议或见解吗?

来自Jon Skeet的操作符之间,增加了包容性标志

public static class BetweenExtension
{
    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 lowerBound = (inclusive)
                  ? Expression.GreaterThanOrEqual(key,Expression.Constant(low))
                  : Expression.GreaterThan(key,Expression.Constant(low));

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

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

        return source.Where(lambda);
    }
}

使用“int”键进行上述工作测试

[TestFixture]
public class BetweenIntTests
{
    public class SampleEntityInt
    {
        public int SampleSearchKey { get; set; }
    }

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

    [Test]
    public void BetweenIntInclusive()
    {
        var sampleData = BuildSampleEntityInt(1,3,10,11,12,15);
        var query = sampleData.Between(s => s.SampleSearchKey,10);
        Assert.AreEqual(2,query.Count());
    }

    [Test]
    public void BetweenIntNotInclusive()
    {
        var sampleData = BuildSampleEntityInt(1,2,false);
        Assert.AreEqual(2,query.Count());
    }
}

使用“字符串”键进行上述非工作测试

[TestFixture]
public class BetweenStringsTests
{

    public class SampleEntityString
    {
        public string SampleSearchKey { get; set; }
    }

    private IQueryable<SampleEntityString> BuildSampleEntityString(params int[] values)
    {
        return values.Select(
               value =>
               new SampleEntityString() {SampleSearchKey = value.ToString() }).AsQueryable();
    }

    [Test]
    public void BetweenStringInclusive()
    {
        var sampleData = BuildSampleEntityString(1,"3","10");
        Assert.AreEqual(2,query.Count());
    }

    [Test]
    public void BetweenStringNotInclusive()
    {
        var sampleData = BuildSampleEntityString(1,"2","11",query.Count());
    }
}

解决方法

您必须调用string.CompareTo方法作为表达式树的一部分.然后,您可以测试其结果.要查看它的外观,请在调试器中查看以下值:

Expression<<Func<string,bool>> filter = str => str.CompareTo("abc") > 0;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读