tags:

views:

102

answers:

3

Here is one I am working on:

var fStep =
            from insp in sq.Inspections
            where insp.TestTimeStamp > dStartTime && insp.TestTimeStamp < dEndTime
                && insp.Model == "EP" && insp.TestResults != "P"
            group insp by new { insp.TestResults, insp.FailStep } into grp

            select new
            {
                FailedCount = (grp.Key.TestResults == "F" ? grp.Count() : 0),
                CancelCount = (grp.Key.TestResults == "C" ? grp.Count() : 0),
                grp.Key.TestResults,
                grp.Key.FailStep,
                PercentFailed = Convert.ToDecimal(1.0 * grp.Count() /tcount*100)

            } ;

I would like to orderby one or more of the fields in the select projection.

+1  A: 

wrap the whole query in parentheses and

.OrderBy(x => x.FailedCount).ThenBy(x => x.CancelCount);
David
The second `OrderBy` should be `ThenBy`.
Mark Byers
please show example
Joe Pitz
A: 

You can move the select value to a let assignment and then build an order by after that.

var fStep =
    from insp in sq.Inspections
    where insp.TestTimeStamp > dStartTime && insp.TestTimeStamp < dEndTime
       && insp.Model == "EP" && insp.TestResults != "P"
    group insp by new { insp.TestResults, insp.FailStep } into grp
    let newInsp = new
    {
        FailedCount = (grp.Key.TestResults == "F" ? grp.Count() : 0),
        CancelCount = (grp.Key.TestResults == "C" ? grp.Count() : 0),
        grp.Key.TestResults,
        grp.Key.FailStep,
        PercentFailed = Convert.ToDecimal(1.0 * grp.Count() / tcount * 100)

    }
    orderby newInsp.FailedCount, newInsp.CancelCount
    // or this ...
    //orderby newInsp.FailedCount
    //orderby newInsp.CancelCount
    select newInsp;
;
Matthew Whited
Generated an error upon execution:Cannot order by type '<>f__AnonymousType6`2[System.Int32,System.Int32]'.
Joe Pitz
drop the `new ...` and replace it with `orderby newInsp.FailedCount, newInsp.CancelCount`
Thomas Levesque
Thanks Thomas... Never tried to run it (only had a mocked data model to make sure it at least compiled.)
Matthew Whited
+3  A: 

The simplest change is probably to use a query continuation:

var fStep =
        from insp in sq.Inspections
        where insp.TestTimeStamp > dStartTime && insp.TestTimeStamp < dEndTime
            && insp.Model == "EP" && insp.TestResults != "P"
        group insp by new { insp.TestResults, insp.FailStep } into grp
        select new
        {
            FailedCount = (grp.Key.TestResults == "F" ? grp.Count() : 0),
            CancelCount = (grp.Key.TestResults == "C" ? grp.Count() : 0),
            grp.Key.TestResults,
            grp.Key.FailStep,
            PercentFailed = Convert.ToDecimal(1.0 * grp.Count() /tcount*100)

        } into selection
        orderby selection.FailedCount, selection.CancelCount
        select selection;

That's mostly equivalent to using "let", to be honest - the real difference is that let introduces a new range variable, whereas a query continuation effectively starts a new scope of range variables - you couldn't refer to grp within the bit after into selection for example.

It's worth noting that this is exactly the same as using two statements:

var unordered =
        from insp in sq.Inspections
        where insp.TestTimeStamp > dStartTime && insp.TestTimeStamp < dEndTime
            && insp.Model == "EP" && insp.TestResults != "P"
        group insp by new { insp.TestResults, insp.FailStep } into grp
        select new
        {
            FailedCount = (grp.Key.TestResults == "F" ? grp.Count() : 0),
            CancelCount = (grp.Key.TestResults == "C" ? grp.Count() : 0),
            grp.Key.TestResults,
            grp.Key.FailStep,
            PercentFailed = Convert.ToDecimal(1.0 * grp.Count() /tcount*100)

        };

var fStep = from selection in unordered
            orderby selection.FailedCount, selection.CancelCount
            select selection;
Jon Skeet
Works just fine
Joe Pitz