如何使用LinqKit的PredicateBuilder构建带Or条件的C# LINQ查询?
解决LinqKit PredicateBuilder结合Include查询的编译错误问题
问题背景
原本有一段可正常运行的LINQ查询,通过多次Where逐步过滤结果,但因业务需求需要添加0至多个OR条件,标准LINQ无法满足,遂尝试使用LinqKit的PredicateBuilder,却在结合Include关联查询时出现编译错误。
原标准LINQ代码
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 ); if (searchModel.BookingStatusId != null) { booking = booking.Where(b => b.BookingStatusId == searchModel.BookingStatusId); }
PredicateBuilder条件构建代码
var predicate = PredicateBuilder.New<Booking>(true); if (searchModel.PoNumber != null) { predicate = predicate.And(b => b.PoNumber.ToString().StartsWith(searchModel.PoNumber.ToString())); }
错误的查询代码
booking = _context.Bookings .Include(v => v.Vendor) .Include(v => v.PurchaseOrder) .ThenInclude(v => v.PurchaseOrderDestinations) .Include(l => l.LineLevelBookings) .Include(d => d.BookingDangerousGoods) .AsExpandable() .Where(t => predicate) .ToList();
错误提示
Cannot convert Lambda Expression to intended delegate type because some of the return trypes in the block are not implicitly convertible to the delegate return type
解决方案
编译错误的核心原因是Where方法的参数使用错误:你将predicate直接嵌套在Lambda表达式中,而正确用法是直接传入predicate本身,或调用其Invoke方法。
修正写法1:直接传入predicate
这是最简洁的用法,直接将PredicateBuilder构建的表达式传入Where:
booking = _context.Bookings .Include(v => v.Vendor) .Include(v => v.PurchaseOrder) .ThenInclude(v => v.PurchaseOrderDestinations) .Include(l => l.LineLevelBookings) .Include(d => d.BookingDangerousGoods) .AsExpandable() .Where(predicate) .ToList();
修正写法2:Lambda中调用Invoke(适用于需额外组合逻辑的场景)
如果需要在Where中结合其他条件,可以通过Invoke方法调用predicate:
booking = _context.Bookings .Include(v => v.Vendor) .Include(v => v.PurchaseOrder) .ThenInclude(v => v.PurchaseOrderDestinations) .Include(l => l.LineLevelBookings) .Include(d => d.BookingDangerousGoods) .AsExpandable() .Where(t => predicate.Invoke(t)) .ToList();
添加OR条件示例
若需实现多条件OR逻辑,直接使用PredicateBuilder的Or方法即可:
if (searchModel.CustomerName != null) { predicate = predicate.Or(b => b.CustomerName.Contains(searchModel.CustomerName)); }
内容的提问来源于stack exchange,提问作者bilpor
相关产品推荐
相关产品推荐

