简体   繁体   中英

ASP.Net C# equivalent to Coldfusion cfoutput GROUP

We are currently converting Coldfusion websites over to ASP.NET C#. We have a report that uses 3-level cfoutput GROUP (first grouping by year, then by agency, then by attorney, and getting the total # of cases assigned to them).

I am having a hard time finding an example of how to convert this to ASP.NET.

<cfquery name="getRecords" datasource="datasource">
    select datepart(yyyy, dtReceived) as [year], agencies.code, users.lname, users.fname        
    from cases left outer join users on cases.users_id=users.users_id
        left outer join agencies on cases.agencies_id = agencies.agencies_id   
    order by datepart(yyyy,dtReceived) desc,agencies.code, lname,fname
</cfquery>

<table>
<cfoutput query="getRecords" group="YEAR">
    <tr>
        <td>#YEAR#</td>
        <td>Office</td>
        <td>## Attorney(s)</td>
        <td>## Suspense(s)</td>
    </tr>    
    <cfoutput group="CODE">         
        <tr>
            <td>&nbsp;</td>
            <td>#htmleditformat(CODE)#</td>         
            <cfset i = 0>
            <cfoutput group="LNAME">
                <cfset i = i+1>
            </cfoutput>

            <td>#i#</td>

            <cfset j = 0>
            <cfoutput>
                <cfset j = j+1>
            </cfoutput>

            <td><strong>#j#</td>
        </tr>   

    <cfoutput group="LNAME">
            <tr>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>#htmleditformat(LNAME)#, #htmleditformat(FNAME)#</td>

                <cfset h = 0>
                <cfoutput>
                    <cfset h = h+1>
                </cfoutput>

                <td>#h#</td>
            </tr>
            </cfoutput>

    <tr>
        <td colspan="4">&nbsp;<br>&nbsp;</td>
    </tr>
    </cfoutput>


</cfoutput>
</table>

Not as nice as ColdFusion, but you could use linq to group results.

Lets say you have a List of objects like so

List<Case> Cases = new List<Case>() 
        {
            new Case(){ Year = 2001, Agency = "Agency1", Attorney="Atticus Finch", CaseNumber = 1},
            new Case(){ Year = 2001, Agency = "Agency1", Attorney="Atticus Finch", CaseNumber = 2},
            new Case(){ Year = 2001, Agency = "Agency1", Attorney="Ben Matlock", CaseNumber = 3},
            new Case(){ Year = 2002, Agency = "Agency1", Attorney="Atticus Finch", CaseNumber = 99},
            new Case(){ Year = 2002, Agency = "Agency1", Attorney="Ben Matlock", CaseNumber = 22},
            new Case(){ Year = 2002, Agency = "Agency2", Attorney="Johnny Cochran", CaseNumber = 12},
            new Case(){ Year = 2003, Agency = "Agency2", Attorney="Mark Geragos", CaseNumber = 14},
            new Case(){ Year = 2003, Agency = "Agency3", Attorney="Robert Shapiro", CaseNumber = 29}
        };

public class Case {

    public int CaseNumber { get; set; }
    public int Year { get; set; }
    public string Agency { get; set; }
    public string Attorney { get; set; }

}

You can use Linq to do some grouping.

var caseList = from c in Cases
                   group c by new { c.Year } into yrgrp
                   orderby yrgrp.Key.Year
                   select new
                   {
                       Year = yrgrp.Key.Year,
                       Agencies = from d in yrgrp
                                  group d by new { d.Agency} into agencygrp
                                  select new
                                  {
                                      Agency = agencygrp.Key.Agency,
                                      Total = agencygrp.Count(),
                                      Attorneys = from e in agencygrp
                                                  group e by e.Attorney into attorneygrp
                                                  select new 
                                                  {
                                                     Attorney = attorneygrp.Key,
                                                     Cases = attorneygrp,
                                                     Total = attorneygrp.Count()

                                                  }

                                  }
                   };

Ill admit it doesn't look pretty.

You can then loop through your new list, and output it in a table, or in my example just to the console.

foreach (var item in caseList)
    {
        Console.WriteLine(item.Year);
        foreach (var agency in item.Agencies)
        {
            Console.WriteLine( agency.Agency + " Number Cases:" + agency.Total + " Number Attorneys:" + agency.Attorneys.Count());

            foreach (var attorney in agency.Attorneys)
            {
                Console.WriteLine(attorney.Attorney + " Number Cases: " + attorney.Total );

                foreach (var cases in attorney.Cases)
                {
                    Console.WriteLine("Case #" + cases.CaseNumber);
                }
            }

        }
    }
        Console.ReadKey();

    }

This outputs..

2001
Agency1 Number Cases:3 Number Attorneys:2
Atticus Finch Number Cases: 2
Case #1
Case #2
Ben Matlock Number Cases: 1
Case #3
2002
Agency1 Number Cases:2 Number Attorneys:2
Atticus Finch Number Cases: 1
Case #99
Ben Matlock Number Cases: 1
Case #22
Agency2 Number Cases:1 Number Attorneys:1
Johnny Cochran Number Cases: 1
Case #12
2003
Agency2 Number Cases:1 Number Attorneys:1
Mark Geragos Number Cases: 1
Case #14
Agency3 Number Cases:1 Number Attorneys:1
Robert Shapiro Number Cases: 1
Case #29

According to what I can find online, ASP does not mirror this functionality. There may be a recent release that does, but I can't find anything regarding that.

In languages without this functionality, this is one method to duplicate it. (It's not as a pretty, but each language has benefits and drawbacks.). This is part-psuedocode so it's not going to work as is in any language.

var cYear = "";
var cAgency = "":
var cAtt = "";
[output loop] {
    if (cYear != GetRecords.Year) {
        // output tr showing GetRecords.Year
        cYear = GetRecords.Year;
        cAgency = ""; // Set these to blank in case the next row starts with thee same as the last finishes with. Otherwise the display would be screwed up.
        cAtt = "";
    } 
    if (cAgency != GetRecords.Agency) {
        // output tr showing GetRecords.Agency
        cAgency = GetRecords.Agency;
        cAtt = "";
    }
    if (cAtt != GetRecords.Attorney} {
        cAtt = GetRecords.Attorney;
        // output tr showing GetRecords.Attorney.
    }

    //output the data row
}

Each tier resets the values related to the next tier so that if the last row of the last parent group matches a agency or attorney, it doesn't screw up the display.

As to the counting you're doing for groups, you can do this in your query using count() on subqueries to obtain the counts you're looking for. Even in CF, which makes such simple counting easy (as far as amount of code required), it's better to do it codeside.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM