如何结合PredicateBuilder动态构建带关联查询的Linq多条件筛选语句?
问题
我一直在寻找动态创建Linq语句的示例,但始终没有找到合适的答案。我的初始代码如下:
IQueryable<Booking> booking;
随后我通过Lambda表达式将若干Booking数据填充到该IQueryable中。每个Booking实体包含4个可空布尔类型的审批原因字段(filter1至filter4),取值可为null、1或0。
当用户仅选择filter1作为筛选条件时,我会使用如下语句:
booking = booking.Where(b => b.filter1 == 1)
这能正常工作,但我希望实现:仅当用户选择对应筛选条件时,才将该条件以逻辑或(||)的方式加入Where子句,即最终语句形如:booking = booking.Where(b => b.filter1 == 1 || b.filter2 == 1....)
有人建议我使用PredicateBuilder,但我看到的示例都是针对单一类型初始化,比如:
var predicate = PredicateBuilder.True<Class1>();
而我的初始Linq查询包含多个Include关联查询,代码如下:
IQueryable<Booking> booking; booking = (from b in _context.Bookings.Include(v => v.Vendor).Include(v => v.PurchaseOrder).ThenInclude(v => v.PurchaseOrderDestinations).Include(l => l.LineLevelBookings).Include(d => d.BookingDangerousGoods) select b);
我不确定PredicateBuilder能否适配这种包含关联查询的场景,特此请教如何实现需求。
解决方案
PredicateBuilder完全适配你这种带Include关联查询的场景——Include只是告诉EF要加载哪些关联实体数据,不会影响主实体Booking的筛选逻辑,你只需要针对Booking类型构建筛选谓词即可。
具体实现步骤如下:
- 初始化一个始终为真的基础谓词(逻辑或的初始值设为True,后续拼接的条件才会生效)
- 根据用户的筛选选择,动态用
Or拼接对应条件 - 最后将构建好的谓词传入
Where方法
完整代码示例:
// 初始化带关联查询的基础IQueryable IQueryable<Booking> bookingQuery = _context.Bookings .Include(v => v.Vendor) .Include(v => v.PurchaseOrder).ThenInclude(v => v.PurchaseOrderDestinations) .Include(l => l.LineLevelBookings) .Include(d => d.BookingDangerousGoods); // 初始化PredicateBuilder,针对Booking类型 var predicate = PredicateBuilder.True<Booking>(); // 用变量标识用户是否选择了对应筛选条件(实际场景可替换为前端传入的参数) bool userSelectedFilter1 = true; bool userSelectedFilter2 = false; bool userSelectedFilter3 = true; bool userSelectedFilter4 = false; // 动态拼接逻辑或条件 if (userSelectedFilter1) { predicate = predicate.Or(b => b.filter1 == 1); } if (userSelectedFilter2) { predicate = predicate.Or(b => b.filter2 == 1); } if (userSelectedFilter3) { predicate = predicate.Or(b => b.filter3 == 1); } if (userSelectedFilter4) { predicate = predicate.Or(b => b.filter4 == 1); } // 应用筛选条件 var filteredBookings = bookingQuery.Where(predicate);
如果用户没有选择任何筛选条件,PredicateBuilder.True<Booking>()会生成一个始终为真的条件,此时查询会返回所有数据,符合预期。
内容的提问来源于stack exchange,提问作者bilpor
相关产品推荐
相关产品推荐

