I have a quite complex Linq query that worked fine in standard Linq. However, I need to change the way the query gets built and depending on user selection include 0:n 'Or' statements in the query.
So to give some context, my original query was built up in the following way:
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);
}
and I'd have a number of these and the booking
object would gradually reduce as each criteria was met.
I've now got a situation where I need to change this because the query is more complex and 'standard' linq is no longer good enough.
So I'm trying to use PredicateBuilder
.
I start with:
var predicate = PredicateBuilder.New<Booking>(true);
and I'm now building the predicate up in a similar way, but this also includes the complex parts:
if (searchModel.PoNumber != null)
{
predicate = predicate.And(b => b.PoNumber.ToString().StartsWith(searchModel.PoNumber.ToString()));
}
So now I'm at the point where from my origial Line I need to include Vendor, purchaseOrder etc.
And this is my sticking point.
I'm trying :
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();
but predicate redlines with:
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
booking = _context.Bookings
.Include(v => v.Vendor)
.Include(v => v.PurchaseOrder)
.ThenInclude(v => v.PurchaseOrderDestinations)
.Include(l => l.LineLevelBookings)
.Include(d => d.BookingDangerousGoods)
.Where(predicate) // note that we don't use lambda here
.ToList();
From my use experience in both classic EF and EF Core, I didn't have to use .AsExpandable()
before applying predicate.