简体   繁体   English

扩展IQueryable并解析属性

[英]Extending IQueryable and parsing a property

I'm fairly new to linq and wanted to delve in a bit deeper by extending IQueryable. 我对linq很新,并希望通过扩展IQueryable来深入研究。 I want to create a simple extension method that queries a date range. 我想创建一个查询日期范围的简单扩展方法。 Something that will be the equivalent to: 相当于的东西:

IQuerable.Where(x => x.Date > fromDate && x.Date < toDate);

but with some extra processing on the dates. 但在日期上有一些额外的处理。 I want to be able to parse a property to perform the query so the method call will be something like: 我希望能够解析一个属性来执行查询,所以方法调用将是这样的:

IQueryable.WhereDateRange(x => x.Date, fromDate, toDate);
IQueryable.WhereDateRange(x => x.AnotherDate, fromDate, toDate);

I've been looking into something like below but I'm not entirely sure what I'm doing 我一直在寻找下面的东西,但我不完全确定我在做什么

public static IQueryable<T> WhereDateRange<T>(this IQueryable<T> source, Func<T, DateTime> getter, DateTime from, DateTime to) {
//query here
}

Is this possible and if so how do I do it? 这是可能的,如果是这样,我该怎么做?

Untested, but: 未经测试,但是:

public static IQueryable<T> WhereDateRange<T>(
    this IQueryable<T> source, Expression<Func<T, DateTime>> getter,
    DateTime from, DateTime to)
{
    Expression body = getter.Body;

    var predicate = Expression.Lambda<Func<T, bool>>(
        Expression.And(
            Expression.GreaterThan(body, Expression.Constant(from)),
            Expression.LessThan(body, Expression.Constant(to))
        ),
        getter.Parameters);
    return source.Where(predicate);
}

For info, though; 但是,有关信息; I usually assume that a range is >= start and < end , so I'd use Expression.GreaterThanOrEqual . 我通常假设范围是>= start< end ,所以我使用Expression.GreaterThanOrEqual

Making that more reusable (and noting that I'm using GreaterThanOrEqual here): 使其更可重用(并注意到我在这里使用GreaterThanOrEqual ):

public static IQueryable<T> WhereInRange<T, TValue>(
    this IQueryable<T> source, Expression<Func<T, TValue>> selector,
    TValue from, TValue to)
{
    Expression body = selector.Body;

    var predicate = Expression.Lambda<Func<T, bool>>(
        Expression.And(
            Expression.GreaterThanOrEqual(
                body, Expression.Constant(from, typeof(TValue))),
            Expression.LessThan(
                body, Expression.Constant(to, typeof(TValue)))
        ),
        selector.Parameters);
    return source.Where(predicate);
}

(need to specify the TValue on the constants in this case, since null will otherwise cause big problems) (在这种情况下需要在常量上指定TValue ,因为null否则会导致大问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM