基于运行时的表达式动态查询
Dynamic Queries with Expressions based on runtime
我正在使用 EF Core 和 .NET 5.0。
我的存储库有一个这样的方法:
public async Task<IEnumerable<Report>> GetByAsync(Expression<Func<Report, bool>> expression)
{
return await DbSet.Where(expression).ToListAsync();
}
我想实现一个Service
的方法如下:
public async Task<IEnumerable<ReportResponse>> GetByAsync(int? productId, int? brandId, int? modelId, int? lineId, DateTime from, DateTime to)
{
var reports = await _repository.GetByAsync(
r => r.ProductId == productId &&
r.BrandId == brandId &&
r.ModelId == modelId &&
r.LineId == lineId &&
r.Date >= from && r.Date <= to);
// other staff
}
更新
想要得到结果,而不是创建单独的方法,基于输入是否有价值。
例如:
GetByAsync(1, null, null, null, '2022-05-01', '2022-06-01')
应该忽略没有值的类型。
并且:
var reports = await _repository.GetByAsync(r => r.ProductId == 1 && r.Date >= '2022-05-01' && r.Date <= '2022-06-01');
我试过 dynamic queries 但无法控制。
您需要的是某种动态谓词生成器,您可以使用此实用程序 class:https://gist.github.com/YoussefSell/ec50f079dd3d1a192ba1f5cd5df2d64d
将 PredicateBuilder class 导入项目后,实际实现如下:
public async Task<IEnumerable<ReportResponse>> GetByAsync(int? productId,
int? brandId,
int? modelId,
int? lineId,
DateTime? from,
DateTime? to)
{
var predicate = PredicateBuilder.True<Report>();
if (productId.HasValue)
predicate = predicate.And(p => p.ProductId == productId);
if (brandId.HasValue)
predicate = predicate.And(p => p.BrandId== brandId);
if (modelId.HasValue)
predicate = predicate.And(p => p.ModelId == modelId);
if (lineId.HasValue)
predicate = predicate.And(p => p.LineId == lineId);
if (from.HasValue)
predicate = predicate.And(p => p.Date >= from);
if (to.HasValue)
predicate = predicate.And(p => p.Date <= to);
// pass the predicate
var reports = await _repository.GetByAsync(predicate);
// other code ...
}
我正在使用 EF Core 和 .NET 5.0。
我的存储库有一个这样的方法:
public async Task<IEnumerable<Report>> GetByAsync(Expression<Func<Report, bool>> expression)
{
return await DbSet.Where(expression).ToListAsync();
}
我想实现一个Service
的方法如下:
public async Task<IEnumerable<ReportResponse>> GetByAsync(int? productId, int? brandId, int? modelId, int? lineId, DateTime from, DateTime to)
{
var reports = await _repository.GetByAsync(
r => r.ProductId == productId &&
r.BrandId == brandId &&
r.ModelId == modelId &&
r.LineId == lineId &&
r.Date >= from && r.Date <= to);
// other staff
}
更新
想要得到结果,而不是创建单独的方法,基于输入是否有价值。
例如:
GetByAsync(1, null, null, null, '2022-05-01', '2022-06-01')
应该忽略没有值的类型。
并且:
var reports = await _repository.GetByAsync(r => r.ProductId == 1 && r.Date >= '2022-05-01' && r.Date <= '2022-06-01');
我试过 dynamic queries 但无法控制。
您需要的是某种动态谓词生成器,您可以使用此实用程序 class:https://gist.github.com/YoussefSell/ec50f079dd3d1a192ba1f5cd5df2d64d
将 PredicateBuilder class 导入项目后,实际实现如下:
public async Task<IEnumerable<ReportResponse>> GetByAsync(int? productId,
int? brandId,
int? modelId,
int? lineId,
DateTime? from,
DateTime? to)
{
var predicate = PredicateBuilder.True<Report>();
if (productId.HasValue)
predicate = predicate.And(p => p.ProductId == productId);
if (brandId.HasValue)
predicate = predicate.And(p => p.BrandId== brandId);
if (modelId.HasValue)
predicate = predicate.And(p => p.ModelId == modelId);
if (lineId.HasValue)
predicate = predicate.And(p => p.LineId == lineId);
if (from.HasValue)
predicate = predicate.And(p => p.Date >= from);
if (to.HasValue)
predicate = predicate.And(p => p.Date <= to);
// pass the predicate
var reports = await _repository.GetByAsync(predicate);
// other code ...
}