user2006562
user2006562

Reputation: 75

Add temporary property to list of objects

I have 3 models

public class Payroll
{
    public int ID { get; set; }

    public DateTime Date { get; set; }

    public int PayCategoryID { get; set; }

    public virtual PayCategory PayCategory { get; set; }
}

this one:

public class PayCategory
{
    public int ID { get; set; }

    public string PayScenario { get; set; }

    public int PayGroupID { get; set; }

    public virtual PayGroup PayGroup { get; set; }
}

and this one:

public class PayGroup 
{
    public int ID { get; set; }

    public string Label { get; set; }

    public string Description { get; set; }

    public string EntryType { get; set; }

}

If I create a List of Payroll I will only get a list of Payroll objects with 4 properties each. I want a list of , where each Payroll object will have the fields Date, PayScenario, Label, Description, and EntryType. I know these can be easily obtained by

    Payroll.PayCategory.PayScenario
    Payroll.PayCategory.PayGroup.Label

etc.

But I am exporting these to an excel document using this generic method:

      public static void Export(List<T> data, string name, Controller controller) 
    {
        XLWorkbook workbook = new XLWorkbook();
        var worksheet = workbook.Worksheets.Add(name);
        worksheet.Cell(1, 1).InsertTable(data); 
        controller.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheet.sheet";
        controller.Response.AddHeader("content-disposition", String.Format(@"attachment;filename={0}.xlsx", name.Replace(" ", "_")));
        using (MemoryStream memoryStream = new MemoryStream())
        {
            workbook.SaveAs(memoryStream);
            memoryStream.WriteTo(controller.Response.OutputStream);
            memoryStream.Close();
        }
        controller.Response.End();

    }

I call from controller like this:

    public ActionResult ExportData()
    {
        var payrolls = (List<Payroll>)Session["payrolls"];
        ExportToExel<Payroll>.Export(payrolls, "Payroll", this);
        return RedirectToAction("Index");
    }

And the results of course give me a simple table with only the value Date in it, (plus some other trash columns like System [...] PayCategory)

Ultimately, I want the properties of these 3 models to be merged (excluding ID's) to give me a single list that I can pass on to the ExportData method. As in, is there a way to add a column to a list of objects? Something similar to

        for(int i = 1; i<payrolls.Count; i++)
              payrolls[i].Add.(payrolls[i].PayCategory.PayScenario);  

which of course, doesn't work. Please don't ask why I don't simply have one model instead of these 3. It's not an option unless I want to hard code values.

Thanks

Upvotes: 1

Views: 5907

Answers (2)

RemedialBear
RemedialBear

Reputation: 644

If you can import Linq, you can do something like:

var payrolls = from aPayroll in (List<Payroll>)Session["payrolls"]
               select new {
                    Date = aPayroll.Date,
                    PayScenario = aPayroll.PayCategory.PayScenario,
                    Label = aPayroll.PayGroup.Label,
                    Description = aPayroll.PayGroup.Description,
                    EntryType = aPayroll.PayGroup.EntryType
               };

That would create an anonymous type with the five properties you want.

Assuming you're using ClosedXML, you should also be able to create a DataTable and send it directly to a worksheet.

Upvotes: 1

wesm
wesm

Reputation: 451

What you are looking for is an "Anonymous Object".

Example usage:

var anonymousObject = new
                    {
                        ID = payrollObj.Id,
                        // other payroll properties
                        PayScenario = payrollObj.PayCategory.PayScenario
                        // other extended properties
                    };

Here's an article about them http://www.c-sharpcorner.com/UploadFile/ff2f08/anonymous-types-in-C-Sharp/

The suggestion here is to create a new anonymous object within your loop and pass that onto your excel function instead of the original payrollObject.

Upvotes: 1

Related Questions