cfisher
cfisher

Reputation: 235

MVC Grid to Excel

I found this project/tutorial:

http://www.codeproject.com/Articles/325103/MVC-Grid-to-Excel-file-download

And it works great! But, I can only get it to work with one Model. So, if I am pulling in just my Organization model it works great. However, I need to fill the GridView by running SQL queries. I was thinking LINQ to SQL would work but I cannot figure it out.

This loads the GridView with data from my Organization model and sends it to the view.

private VAGTCEntities db = new VAGTCEntities();
public ActionResult Index()
{
    ViewBag.Message = "Welcome to ASP.NET MVC!";
    List<Organization> model = db.Organizations.ToList();

    GridView gv = new GridView();
    gv.DataSource = model;
    gv.DataBind();
    Session["Organizations"] = gv;

    return View(model);
}

The view is just a normal one:

@model IEnumerable<VAGTC.Models.Organization>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Download File", "Download")
</p>
<table>
    <tr>
        <th>
            Organization ID
        </th>
        <th>
            Organization Name
        </th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @item.OrganizationID
        </td>
        <td>
            @item.Name
        </td>
    </tr>
}

</table>

When the download link is clicked it calls the Actionresult which calls some Javascript:

public ActionResult Download()
{
    if (Session["Organizations"] != null)
    {
        return new DownloadFileActionResult((GridView)Session["Organizations"], "Organizations.xls");
    }
    else
    {
        return new JavaScriptResult();
    }
}

Simple! But, I cannot figure out how to use LINQ to SQL queries with it. I need to be able to reference multiple tables. For instance, pulling in all the addresses of an Organization in a specific County and State (OrganizationAddress) along with the Organization Name (Organization). I figured I would have to use a ViewModel, however I still could not fill it up.

Organization model:

namespace VAGTC.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    public partial class Organization
    {
        public Organization()
        {
            this.ContactMTMOrganizations = new HashSet<ContactMTMOrganization>();
            this.ContactTitles = new HashSet<ContactTitle>();
            this.OrganizationAddresses = new HashSet<OrganizationAddress>();
            this.OrganizationBusinessTypes = new HashSet<OrganizationBusinessType>();
            this.OrganizationCountries = new HashSet<OrganizationCountry>();
            this.OrganizationEmails = new HashSet<OrganizationEmail>();
            this.OrganizationIndustryCodes = new HashSet<OrganizationIndustryCode>();
            this.OrganizationMemberships = new HashSet<OrganizationMembership>();
            this.OrganizationNotes = new HashSet<OrganizationNote>();
            this.OrganizationPhones = new HashSet<OrganizationPhone>();
            this.OrganizationWebsites = new HashSet<OrganizationWebsite>();
        }

        [Display(Name = "Organization ID:")]
        public int OrganizationID { get; set; }
        [Display(Name = "Organization Name:")]
        public string Name { get; set; }

        public virtual ICollection<ContactMTMOrganization> ContactMTMOrganizations { get; set; }
        public virtual ICollection<ContactTitle> ContactTitles { get; set; }
        public virtual ICollection<OrganizationAddress> OrganizationAddresses { get; set; }
        public virtual ICollection<OrganizationBusinessType> OrganizationBusinessTypes { get; set; }
        public virtual ICollection<OrganizationCountry> OrganizationCountries { get; set; }
        public virtual ICollection<OrganizationEmail> OrganizationEmails { get; set; }
        public virtual ICollection<OrganizationIndustryCode> OrganizationIndustryCodes { get; set; }
        public virtual ICollection<OrganizationMembership> OrganizationMemberships { get; set; }
        public virtual ICollection<OrganizationNote> OrganizationNotes { get; set; }
        public virtual ICollection<OrganizationPhone> OrganizationPhones { get; set; }
        public virtual ICollection<OrganizationWebsite> OrganizationWebsites { get; set; }
    }
}

OrganizationAddress model:

namespace VAGTC.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public partial class OrganizationAddress
    {
        [Display(Name = "Street:")]
        public string StreetID { get; set; }
        [Display(Name = "City:")]
        public string CityID { get; set; }
        [Display(Name = "Organization ID:")]
        public int OrganizationID { get; set; }
        [Display(Name = "Country:")]
        public string CountryNameID { get; set; }
        [Display(Name = "County:")]
        public string CountyNameID { get; set; }
        [Display(Name = "County State:")]
        public string CountyStateID { get; set; }
        [Display(Name = "State:")]
        public string State { get; set; }
        [Display(Name = "Zip-code:")]
        public string ZipCode { get; set; }
        [Display(Name = "Address Type:")]
        public string Type { get; set; }

        public virtual Country Country { get; set; }
        public virtual County County { get; set; }
        public virtual Organization Organization { get; set; }

        public string FullAddress
        {
            get
            {
                return StreetID + ", " + CityID + ", " + State + " " + ZipCode + ", " + CountryNameID;
            }
        }
        public string FullCounty
        {
            get
            {
                return CountyNameID + ", " + CountyStateID;
            }
        }

    }
}

I will highly appreciate a kick in the right direction!

Thank you very much!

Edit*

What I think it boils down to is being able to populate a list like:

List<Organization> model = db.Organizations.ToList();

but from multiple tables. Still playing around with ViewModels but it comes up blank since I cannot figure out how to populate the ViewModel with Linq to SQL.

Upvotes: 1

Views: 734

Answers (1)

Paul Taylor
Paul Taylor

Reputation: 5761

Essentially, you need to do the equivalent of a SQL join between your entities. If you have Lazy Loading enabled, you can access all the entities related to your main Organization entity automatically. If not, you can use eager loading to access the same data (use db.Organizations.Include(o => o.OrganizationAddress).ToList() for example).

Or you can use the Linq to Entities Join method. If you want to use a ViewModel, you might want to create a class that can store the properties you are interested in from Organization and related entities. You just need to populate it's properties from your entity objects (for each item in your Organizations collection in this case).

Upvotes: 1

Related Questions