You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Linq与Entity Framework编写日期范围筛选扩展方法

实现代码

你可以通过原生表达式树构造过滤逻辑,无需依赖第三方库,EF可直接解析生成对应SQL,完整实现如下:

using System.Linq.Expressions;

private static IQueryable<T> FilterOnCorrectSearchDateTime<T>(this IQueryable<T> efQueryable, 
    Expression<Func<T, DateTime>> datePropertySelector, 
    DateTime? dateFrom, 
    DateTime? dateTo)
{
    // 无过滤条件直接返回原查询
    if (!dateFrom.HasValue && !dateTo.HasValue)
        return efQueryable;

    var parameter = datePropertySelector.Parameters[0];
    var propertyAccess = datePropertySelector.Body;
    Expression filterCondition = null;

    // 构造起始日期过滤
    if (dateFrom.HasValue)
    {
        var fromConst = Expression.Constant(dateFrom.Value, typeof(DateTime));
        filterCondition = Expression.GreaterThanOrEqual(propertyAccess, fromConst);
    }

    // 构造结束日期过滤
    if (dateTo.HasValue)
    {
        var toConst = Expression.Constant(dateTo.Value, typeof(DateTime));
        var toCondition = Expression.LessThanOrEqual(propertyAccess, toConst);
        filterCondition = filterCondition == null ? toCondition : Expression.AndAlso(filterCondition, toCondition);
    }

    var filterLambda = Expression.Lambda<Func<T, bool>>(filterCondition, parameter);
    return efQueryable.Where(filterLambda);
}

如果你的实体存在可空DateTime?类型的日期字段,可以新增以下重载适配:

private static IQueryable<T> FilterOnCorrectSearchDateTime<T>(this IQueryable<T> efQueryable, 
    Expression<Func<T, DateTime?>> datePropertySelector, 
    DateTime? dateFrom, 
    DateTime? dateTo)
{
    if (!dateFrom.HasValue && !dateTo.HasValue)
        return efQueryable;

    var parameter = datePropertySelector.Parameters[0];
    var propertyAccess = datePropertySelector.Body;

    // 先过滤可空字段非空的情况
    var hasValueCondition = Expression.Equal(
        Expression.Property(propertyAccess, nameof(DateTime.HasValue)), 
        Expression.Constant(true));
    var valueAccess = Expression.Property(propertyAccess, nameof(DateTime.Value));
    Expression filterCondition = hasValueCondition;

    if (dateFrom.HasValue)
    {
        var fromConst = Expression.Constant(dateFrom.Value, typeof(DateTime));
        var fromCondition = Expression.GreaterThanOrEqual(valueAccess, fromConst);
        filterCondition = Expression.AndAlso(filterCondition, fromCondition);
    }

    if (dateTo.HasValue)
    {
        var toConst = Expression.Constant(dateTo.Value, typeof(DateTime));
        var toCondition = Expression.LessThanOrEqual(valueAccess, toConst);
        filterCondition = Expression.AndAlso(filterCondition, toCondition);
    }

    var filterLambda = Expression.Lambda<Func<T, bool>>(filterCondition, parameter);
    return efQueryable.Where(filterLambda);
}

调用方式和你预期的完全一致:

EFquerable = EFquerable.FilterOnCorrectSearchDateTime(s=>s.PlannedEndDate, searchCriteria.PlannedEndDateFrom, searchCriteria.PlannedEndDateTo);

额外注意事项

  • 你原有代码存在逻辑错误:双条件判断中d.PlannedEndDate > searchCriteria.PlannedEndDateTo写反,会导致范围过滤完全失效,上述实现默认使用包含边界的比较(>=/<=),如果业务需要开闭区间可自行调整比较方法。
  • 建议增加入参校验:如果传入的dateFrom晚于dateTo,可直接抛出参数异常或跳过过滤,避免生成无效查询返回空结果。
  • 该实现完全兼容多日期字段叠加过滤,不会互相干扰,EF解析生成的SQL和手写Where的效果完全一致,无性能损耗。

内容的提问来源于stack exchange,提问作者Jerker Pihl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 23:00:00