I need to generate several reports, and many of them will simply be a table of entities from my database. The entities could be of any type, and I won't always need the entire entity.
My current approach is to create a ViewModel that contains a field of type List<List<string>>
, which represents my table, where each row is a List of cells. Then, the view only needs to enumerate through each row and column to create the table.
public class ListReportViewModel
{
public string Title;
public List<string> Headings;
public List<List<string>> Rows;
}
Then I have controller code to populate Headings and Rows:
// Get the entities for the report
var tickets = ( from t in _db.Ticket.Include("Company").Include("Caller")
select t );
// Populate the column headings
data.Headings = new List<string>();
data.Headings.Add( "Ticket ID" );
data.Headings.Add( "Company" );
data.Headings.Add( "Caller" );
data.Headings.Add( "Reason for Call" );
// Temporary staging variables
List<List<string>> rows = new List<List<string>>();
List<string> row;
// Populate temporary variables
foreach ( var ticket in tickets )
{
row = new List<string>();
row.Add( ticket.TicketID.ToString() );
row.Add( ticket.Company.Name );
row.Add( ticket.Caller.FirstName + " " + ticket.Caller.LastName );
row.Add( ticket.Subject );
rows.Add( row );
}
// Populate ViewModel field
data.Rows = rows;
Although this works, it seems inefficient. I'm looping through my entire result set just to populate the ViewModel, then the view is going to have to loop through it again to build the report.
My question: Is there a simpler way to do this? If I could get my Linq query to return an IEnumerable<IEnumerable<string>>
, then I could just use the line "data.Rows = tickets
" and the view would be able to loop through this itself.
I think there must be a better way to do this that I'm not aware of.