How to cancel Where IQueryable clause

I created an extension method to encapsulate some logic where (this is a very simplified version):

public static IQueryable<Cargo> ReadyToCarry(this IQueryable<Cargo> q)
{
    VehicleType[] dontNeedCouple = new VehicleType[] { VehicleType.Sprinter, VehicleType.Van, VehicleType.Truck };

    return q.Where(c => c.DriverId > 0 && c.VehicleId > 0)
            .Where(c => c.CoupleId > 0 || dontNeedCouple.Contains(c.Vehicle.Type));
}

Therefore, I can use it as follows:

using (var ctx = new MyNiceContext())
{
    var readyCargo = ctx.Cargos.ReadyToCarry().OrderBy(c => c.Id).ToList();
    // ...more code
}

What works well is translated into SQL and implemented by the Entity Framework. Now I have another place where I need loads that are not ready to carry, which means that I need something completely different.

My idea was something like this:

public static IQueryable<Cargo> NotReadyToCarry(this IQueryable<Cargo> q)
{
    return !q.ReadyToCarry(); // ofc this doesn't work...
}

using (var ctx = new MyNiceContext())
{
    var readyCargo = ctx.Cargos.NotReadyToCarry().OrderBy(c => c.Id).ToList();
    // OR maybe
    var readyCargo = ctx.Cargos.ReadyToCarry(false).OrderBy(c => c.Id).ToList(); // somehow use that bool param to reverse the logic when false
}

I did not want to recreate the inverse logic from scratch, so if I had to change it once, I would change one unique place.

I accept alternatives to this approach, as this is a new project.

+4
1

Except():

var readyCargo = ctx.Cargos.ReadyToCarry().OrderBy(c => c.Id);
var notReadyCargo = ctx.Cargos.Except(readyCargo);

ReadyToCarry():

public static IQueryable<Cargo> ReadyToCarry(this IQueryable<Cargo> q, bool ready = true)
{
    VehicleType[] dontNeedCouple = new VehicleType[] { VehicleType.Sprinter, VehicleType.Van, VehicleType.Truck };

    if (ready)
    {
        return q.Where(c => c.DriverId > 0 && c.VehicleId > 0)
                .Where(c => c.CoupleId > 0 || dontNeedCouple.Contains(c.Vehicle.Type));
    }
    else
    {
        // logic to get not ready for carrying
    }
}

:

public static IQueryable<Cargo> ReadyToCarry(this IQueryable<Cargo> q, bool ready = true)
{
    VehicleType[] dontNeedCouple = new VehicleType[] { VehicleType.Sprinter, VehicleType.Van, VehicleType.Truck };

    var readyToCarry = q.Where(c => c.DriverId > 0 && c.VehicleId > 0)
                        .Where(c => c.CoupleId > 0 || dontNeedCouple.Contains(c.Vehicle.Type));

    if (ready)
    {
        return readyToCarry;
    }
    else
    {
        return q.Except(readyToCarry);
    }
}

, , , . .

+6

Source: https://habr.com/ru/post/1670423/


All Articles