Riz
Riz

Reputation: 6676

c# lambda expression using Sum for multiple comparisons

I'm trying use the Sum method in a lambda expression for a comparison, but I want to use it for multiple comparisons. How do I accomplish this? I've looked at "Let" and "SelectMany", but I haven't been able to find an answer.

Below is what the code looks like:

return _dbContext.All<Table>()
            .Where(table => table.CurrentLevel <= salesCriteria.MaxTableLevel)
            .Where(table =>  table.Leg
                            .Where(leg=> salesCriteria.StartDate <= leg.AddDate)
                            .Where(leg=> leg.AddDate <= salesCriteria.EndDate)
                            .Sum(leg => leg.Width) <= salesCriteria.MaxGoalAmount);

As you can see, I'm trying to get all Tables with certain criteria that have Legs with certain criteria and whose width all add up to be less than a certain value. I would also like to make sure that the Sum is greater than a certain min value. However, I can't do that here since as soon as I do .Sum, I lose the list. So how would I accomplish that here? All I want is minValue <= .Sum() <= maxValue

Upvotes: 0

Views: 3720

Answers (2)

AakashM
AakashM

Reputation: 63340

To get the power of let, you need to switch from method-chaining syntax to query expression syntax. Try this:

var goodTables = 
    from table in _dbContext.All<Table>()
    where table.CurrentLevel <= salesCriteria.MaxTableLevel
    let sumOfWidthOfGoodLegs = 
        table.Leg
        .Where(leg=> salesCriteria.StartDate <= leg.AddDate)
        .Where(leg=> leg.AddDate <= salesCriteria.EndDate)
        .Sum(leg => leg.Width)    
    where sumOfWidthOfGoodLegs <= salesCriteria.MaxGoalAmount
    // can insert another where on sumOfWidthOfGoodLegs here as required
    select table;

return goodTables.ToList();

I note that this is checking the width-sum of only the good legs - I'm not convinced this is what you want, but it's what you're doing at present.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499900

It sounds like you want something like:

return _dbContext.All<Table>()
        .Where(table => table.CurrentLevel <= salesCriteria.MaxTableLevel)
        .Select(table => new { 
           table, 
           legWidth = table.Leg
                           .Where(leg=> salesCriteria.StartDate <= leg.AddDate)
                           .Where(leg=> leg.AddDate <= salesCriteria.EndDate)
                           .Sum(leg => leg.Width)
        })
        .Where(x => x.legWidth <= salesCriteria.MaxGoalAmount &&
                    x.legWidth >= salesCriteria.MinGoalAmount)
        .Select(x => x.table);

So the Select here is the equivalent of using a let in a query expression.

As a query expression, this would be:

return from table in _dbContext.All<Table>()
       where table.CurrentLevel <= salesCriteria.MaxTableLevel
       let legWidth = table.Leg
                           .Where(leg=> salesCriteria.StartDate <= leg.AddDate)
                           .Where(leg=> leg.AddDate <= salesCriteria.EndDate)
                           .Sum(leg => leg.Width)
       where legWidth <= salesCriteria.MaxGoalAmount &&
             legWidth >= salesCriteria.MinGoalAmount
       select table;

Upvotes: 1

Related Questions