我今天早上(
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()); } }
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。