Why are my LINQ OrderBys not working?

This LINQ:

public IEnumerable<InventoryItem> GetDepartmentRange(double deptBegin, double deptEnd)
{
    // Break the doubles into their component parts:
    int deptStartWhole = (int)Math.Truncate(deptBegin);
    int startFraction = (int)((deptBegin - deptStartWhole) * 100);
    int deptEndWhole = (int)Math.Truncate(deptEnd);
    int endFraction = (int)((deptBegin - deptEndWhole) * 100);

    return inventoryItems.Where(d => d.dept >= deptStartWhole).Where(e => e.subdept >= startFraction)
        .Where(f => f.dept <= deptEndWhole)
        .Where(g => g.subdept >= endFraction)
        .OrderBy(o => o.dept)
        .OrderBy(s => s.subdept);
}

...returns the expected data when I enter:

http://localhost:28642/api/inventoryitems/GetDeptRange/1.1/79.99/

...namely (subset):

<InventoryItem>
<Description>LID - Blank & Ten PLU</Description>
<ID>110</ID>
<OpenQty>0</OpenQty>
<UPC>110</UPC>
<UnitCost>4</UnitCost>
<UnitList>5</UnitList>
<crv_id>0</crv_id>
<dept>2</dept>
<pksize>1</pksize>
<subdept>10</subdept>
<upc_pack_size>1</upc_pack_size>
<vendor_id>LOCATIONID</vendor_id>
<vendor_item/>
</InventoryItem>

<InventoryItem>
<Description>BLT 6PK LNNR</Description>
<ID>01820000978</ID>
<OpenQty>0</OpenQty>
<UPC>01820000988</UPC>
<UnitCost>19.45</UnitCost>
<UnitList>11.99</UnitList>
<crv_id>0</crv_id>
<dept>10</dept>
<pksize>6</pksize>
<subdept>10</subdept>
<upc_pack_size>1</upc_pack_size>
<vendor_id>CLAREROSE</vendor_id>
<vendor_item/>
</InventoryItem>

<InventoryItem>
<Description>LID - Eleven & Eleven PLU</Description>
<ID>111</ID>
<OpenQty>0</OpenQty>
<UPC>111</UPC>
<UnitCost>4</UnitCost>
<UnitList>5</UnitList>
<crv_id>0</crv_id>
<dept>2</dept>
<pksize>1</pksize>
<subdept>11</subdept>
<upc_pack_size>1</upc_pack_size>
<vendor_id>LOCATIONID</vendor_id>
<vendor_item/>
</InventoryItem>

...but the data is not ordered by dept and subdept (it goes from dept 2, subdept 10 to dept 10, subdept 10, to dept 2, subdept 11. Why is not ordered per the LINQ orderbys? How can I make it order by dept and subdept?

Upvotes: 0

Views: 109

Answers (3)

akousmata
akousmata

Reputation: 1043

They are executing back to back. So it is first ordering by department then separately by subdepartment so the list is left ordered only by subdepartment. You want to use the ThenBy... series of methods as shown in this post:

How to use orderby with 2 fields in linq?

Upvotes: 1

Paweł Bejger
Paweł Bejger

Reputation: 6366

You should use ThenBy:

.Orderby(o => o.debt).ThenBy(s => s.subdept)

Upvotes: 2

yoozer8
yoozer8

Reputation: 7489

Your last OrderBy blows away your first. You're ordering the list by dept, then re-ordering the result by subdept.

What you want to use here is ThenBy to preserve the first ordering.

Your code would look like this:

return inventoryItems.Where(d => d.dept >= deptStartWhole).Where(e => e.subdept >= startFraction)
    .Where(f => f.dept <= deptEndWhole)
    .Where(g => g.subdept >= endFraction)
    .OrderBy(o => o.dept)
    .ThenBy(s => s.subdept);

Upvotes: 9

Related Questions