score:3

Accepted answer

Since in you're example you're multiplying the fraction by 100, i'm assuming the subdept value would only have two digits. If it's the case, perhaps you could try the following code:

public IEnumerable<InventoryItem> GetDepartmentRange(double deptBegin, double deptEnd, string dbContext)
{           
  LoadInventoryItems(dbContext);

  return inventoryItems
    .Where(d => ((d.dept * 100 + d.subdept) >= deptBegin * 100) &&       
                ((d.dept * 100 + d.subdept) <= deptEnd * 100))
    .OrderBy(o => o.dept)
    .ThenBy(s => s.subdept);
}

score:2

A suggestion: create a function that takes in the deptNumber and deptSubNumber, and returns a decimal. Then, use that function in-line in the .Where() statement to process the numbers as a single number, rather than using separate logic (treating dept and sub-dept separately) .

score:3

Your endFraction calculation is wrong:

public IEnumerable<InventoryItem> GetDepartmentRange(double deptBegin, double deptEnd, string dbContext)
{
    LoadInventoryItems(dbContext);
    // 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)((deptEnd - 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)
        .ThenBy(s => s.subdept);
}

score:3

You are using a wrong variable in your calculation here:

var endFraction = (int)((deptBegin - deptEndWhole) * 100);

Replace deptBegin with deptEnd to fix this.

Making this change appears to produce the desired values when tested with the following code:

public void ShowDeptRange(double deptBegin, double deptEnd)
{
    // Break the doubles into their component parts:
    var deptStartW = (int)Math.Truncate(deptBegin);
    var deptStartF = (int)((deptBegin - deptStartW) * 100);
    var deptEndW = (int)Math.Truncate(deptEnd);
    var deptEndF = (int)((deptEnd - deptEndW) * 100);

    Console.WriteLine("{0}.{1}, {2}.{3}",
        deptStartW, deptStartF, deptEndW, deptEndF);
}

void Main()
{
    ShowDeptRange(8.79, 98.87);
}

Also see this answer, which addresses problems with your query's logic.

score:2

An alternative suggestion: is it possible to create a calculated column on the database that simply combines the two fields together in the database, and returns it as a decimal?

Then, use that function in-line in the .Where() statement to process the numbers as a single number, rather than using separate logic (treating dept and sub-dept separately).

Following this, all of the department/sub-department logic in the C# code would be moot.

score:3

Your condition is not correct. Consider following:

int deptStartWhole = 8;
int startFraction = 79;
int deptEndWhole = 98;
int endFraction = 87;

and your condition is:

d.dept >= deptStartWhole && d.subdept >= startFraction
&& d.dept <= deptEndWhole && d.subdept <= endFraction

it will not return row with dept = 12 and subdept = 32, because 32 >= 79 (d.subdept >= startFraction check) is not true.

I think your condition should be

((d.dept == deptStartWhole && d.subdept >= startFraction) || d.dept > deptStartWhole)
&& ((d.dept == deptEndWhole && d.subdept <= endFraction) || d.subdept < deptEndWhole)

It checked subdept only when dept is exactly the same, and otherwise just check dept part, because that's the important one.

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

Related Articles