我需要通过比较int数据范围来执行带where子句的查询。
例如:
class RangeClass
{
public int From{get; set;}
public int To {get; set;}
}
void ExecuteQuery()
{
// prepare a list of range data
List<RangeClass> rangeList = new List<Range>();
rangeList .Add(new rangeClass ...
rangeList .Add(new RangeClass ...
DbContext db = new DbContext();
var query = db.Invoice.Where(p => rangeList.Any(x => p.Price >= x.From && p.Price <= x.To)).ToList();
}
显然,由于要在查询(RangeClass)中使用非原始类型,因此我得到了NotSupportedExcetpion。
是否有一些解决方法可以使用Linq To Entities完成我的查询?
@@编辑
为了阐明我的示例,这里有一些信息:
RangeClass List (in memory list):
1 - From = 1; To = 10;
2 - From = 20; To = 30;
3 - From = 31; To = 40;
发票数据库记录:
1 - Price = 5;
2 - Price = 15;
3 - Price = 20;
我的查询应该返回发票表的第一个(价格5)和最后一个(价格20)记录,因为第二个(价格15)不在我的内存列表中的任何“记录”之间。
由于范围比较可以替换为以下表达式:
_.Price >= r1.From && _.Price <= r1.To ||
_.Price >= r2.From && _.Price <= r2.To ||
...
_.Price >= rN.From && _.Price <= rN.To
您可以动态构建此表达式:
static class RangeHelpers
{
public static IQueryable<T> PropertyFitsAnyRange<T, TProperty>(this IQueryable<T> query, IEnumerable<Range> ranges, Expression<Func<T, TProperty>> propertyToCompareExpr)
{
Expression conditionalExpr = null;
foreach (var range in ranges)
{
var andExpr = Expression.And(
Expression.GreaterThanOrEqual(propertyToCompareExpr.Body, Expression.Constant(range.From)),
Expression.LessThanOrEqual(propertyToCompareExpr.Body, Expression.Constant(range.To)));
conditionalExpr = conditionalExpr == null ? andExpr : Expression.Or(conditionalExpr, andExpr);
}
if (conditionalExpr != null)
{
query = query
.Where(Expression.Lambda<Func<T, bool>>(conditionalExpr, propertyToCompareExpr.Parameters[0]));
}
return query;
}
}
用法:
var invoices = context
.Invoices
.PropertyFitsAnyRange(ranges, _ => _.Price);
PS我相信,那Invoice.Price
是十进制。如果是这样,则Range
类定义应为:
public class Range
{
public decimal From { get; set; }
public decimal To { get; set; }
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句