使用数据库的创建时间作为查询依据,在Abp框架中,实体类实现ICreationAuditedObject接口,或继承CreationAuditedEntity类,使用仓储创建记录时将自动生成CreationTime。
实现
定义按创建日期范围查询(IDateSpanOrientedFilter)接口。
遵守接口隔离原则,将IDateSpanOrientedFilter接口拆分为IStartDateOrientedFilter和IEndDateOrientedFilter接口。
public interface IDateSpanOrientedFilter : IStartDateOrientedFilter, IEndDateOrientedFilter { }
按开始日期查询接口定义如下:
public interface IStartDateOrientedFilter { DateTime? StartDate { get; set; } }
结束日期接口定义如下:
public interface IEndDateOrientedFilter { DateTime? EndDate { get; set; } }
- StartDate:开始日期,记录的CreationTime 大于等于 该日期的记录将被筛选
- EndDate:用户Id,记录的CreationTime 小于 该日期的记录将被筛选
按开始日期查询
创建应用过滤条件方法:ApplyStartDateOrientedFiltered,在此实现拼接LINQ表达式,代码如下:
protected virtual IQueryable<TEntity> ApplyStartDateOrientedFiltered(IQueryable<TEntity> query, TGetListInput input) { if (input is IStartDateOrientedFilter && HasProperty<TEntity>("CreationTime")) { var property = typeof(TEntity).GetProperty("CreationTime"); var filteredInput = input as IStartDateOrientedFilter; if (filteredInput != null && filteredInput.StartDate.HasValue) { Expression originalExpression = null; var parameter = Expression.Parameter(typeof(TEntity), "p"); var dateConstantExpression = Expression.Constant(filteredInput.StartDate.Value, typeof(DateTime)); var propertyAccess = Expression.MakeMemberAccess(parameter, property); var expression = Expression.GreaterThanOrEqual(propertyAccess, dateConstantExpression); var equalExpression = expression != null ? Expression.Lambda<Func<TEntity, bool>>(expression, parameter) : p => false; query = query.Where(equalExpression); } } return query; }
按结束日期查询
创建应用过滤条件方法:ApplyEndDateOrientedFiltered,在此实现拼接LINQ表达式,代码如下:
protected virtual IQueryable<TEntity> ApplyEndDateOrientedFiltered(IQueryable<TEntity> query, TGetListInput input) { if (input is IEndDateOrientedFilter && HasProperty<TEntity>("CreationTime")) { var property = typeof(TEntity).GetProperty("CreationTime"); var filteredInput = input as IEndDateOrientedFilter; if (filteredInput != null && filteredInput.EndDate.HasValue) { Expression originalExpression = null; var parameter = Expression.Parameter(typeof(TEntity), "p"); var dateConstantExpression = Expression.Constant(filteredInput.EndDate.Value, typeof(DateTime)); var propertyAccess = Expression.MakeMemberAccess(parameter, property); var expression = Expression.LessThan(propertyAccess, dateConstantExpression); var equalExpression = expression != null ? Expression.Lambda<Func<TEntity, bool>>(expression, parameter) : p => false; query = query.Where(equalExpression); } } return query; }
请注意,可应用过滤的条件为:
- input需实现IDateSpanOrientedFilter或子接口;
- 实体必须包含“CreationTime”字段。
否则将原封不动返回IQueryable对象。
使用
无需在应用层中更改代码,
在GetAllAlarmInput中实现IDateSpanOrientedFilter接口,代码如下:
public class GetAllAlarmInput : PagedAndSortedResultRequestDto, IDateSpanOrientedFilter { public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } ... }
至此,所有的通用查询接口已实现完成。在这个项目中,我实现了适合我的联合查询方式,你可以根据实际业务需求,扩展和调整查询实现。