title: Export to Excel - LINQ - Include ForeignKey values in .ToList()?
body: <p>I am attempting to add Excel Export functionality to my MVC5/Code-First Entity Framework application via the <a href="https://epplus.codeplex.com/" rel="nofollow noreferrer">EPPlus</a> library. On my Export <code>View</code> I have filled a <code>MultiSelectList</code> with each of my <code>INV_Assets</code> model properties. These then get passed into my <code>ExportController</code> to designate which fields of the model are to be exported.</p>
  
  <p>I've gotten the Headers (via the <code>MultiSelectList</code>) to load into Row1 of Excel and the data from my <code>INV_Assets</code> model to export to excel via EPPlus <code>LoadFromCollection()</code> as below (example):</p>
  
  <p><strong>Code</strong>:</p>
  
  <pre><code>    [HttpPost]
      public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
      {
          ExcelPackage package = new ExcelPackage();
          var ws = package.Workbook.Worksheets.Add("TestExport");
  
          var exportFields = new List&lt;string&gt;();
          foreach (var selectedField in model.SelectedFields)
          {
              // Adds selected fields to [exportFields] List&lt;string&gt;
              exportFields.Add(model.ListOfExportFields.First(s =&gt; s.Key == selectedField).Value);
          }
  
         {
              ws.Cells[1, i + 1].Value = exportFields[i].ToString();
          }
  
          var membersToShow = typeof(INV_Assets).GetMembers().Where(p =&gt; exportFields.Contains(p.Name)).ToArray();
  
          ws.Cells["A2"].LoadFromCollection(_db.INV_Assets.ToList(), false, TableStyles.None, BindingFlags.Default, membersToShow);
  
          var memoryStream = new MemoryStream();
          package.SaveAs(memoryStream);
  
          string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
          string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  
          memoryStream.Position = 0;
          return File(memoryStream, contentType, fileName);
      }
  </code></pre>
  
  <p><strong>Output</strong>:</p>
  
  <p><img src="https://i.stack.imgur.com/MOLj6.jpg" alt="Excel Output"></p>
  
  <p>The only issue I still have is the <code>ForeignKey</code> fields within my model. For example, <code>[Status]</code> is defined in my <code>INV_Assets</code> Model as:</p>
  
  <pre><code>    [Required]
      public int Status_Id { get; set; }
      [ForeignKey("Status_Id")]
      public virtual INV_Statuses Status { get; set; }
  </code></pre>
  
  <p>When the current export executes though, instead of getting say <code>AVAILABLE</code>/<code>RECYCLED</code>, the <code>[Status]</code> column in excel contains <code>"InventoryTracker.Models.INV_Statuses"</code> in every cell for each record exported.</p>
  
  <p>Can anyone offer insight into how to get not only the direct <code>INV_Assets</code> fields exported, but the <code>ForeignKey</code> values for <code>Model, Location, Status, Vendor, Manufacturer, and Type</code> also into Excel?</p>
  
  <p>I did some reading and thought the <code>Include()</code> method would work, but no luck. (Ex.) <code>[Type]</code> still displays <code>InventoryTracker.Models.INV_Types</code> in all record cells using the following code:</p>
  
  <pre><code>ws.Cells["A2"].LoadFromCollection(_db.INV_Assets.Include("Model").Include("Manufacturer").Include("Type").Include("Status").Include("Vendor").ToList(), false, TableStyles.None, BindingFlags.Default, membersToShow);
  </code></pre>
  
  <hr>
  
  <p><strong>EDIT</strong>:</p>
  
  <p>I added <code>using System.Data.Entity</code> to my <code>ExportController</code> which allowed the following to compile:</p>
  
  <pre><code>ws.Cells["A2"].LoadFromCollection(_db.INV_Assets.Include(m =&gt; m.Model.model_description).Include(m =&gt; m.Manufacturer.manufacturer_description).Include(m =&gt; m.Type.type_description).Include(m =&gt; m.Status.status_description).Include(m =&gt; m.Vendor.vendor_name).ToList(), false, TableStyles.None, BindingFlags.Default, membersToShow);
  </code></pre>
  
  <p>I thought this would do the trick, but during execution I receive:</p>
  
  <pre><code>InvalidOperationException was unhandled by user code.
  
  An exception of type 'System.InvalidOPerationException' occurred in EntityFramework.SqlServer.dll but was not handled in user code.
  
  Additional Information: A specified Include path is not valid. The EntityType 'InventoryTracker.DAL.INV_Models' does not declare a naviation property with the name 'model_description'.
  </code></pre>
  
  <p>I don't understand why this is flagging in this manner. <code>INV_Assets</code> has the relation to <code>INV_Models</code> defined thus:</p>
  
  <pre><code>    public int Model_Id { get; set; }
      [ForeignKey("Model_Id")]
      public virtual INV_Models Model { get; set; }
  </code></pre>
  
  <p>And INV_Models defined as:</p>
  
  <pre><code>public class INV_Models
  {
      public int Id { get; set; }
  
      [Required(ErrorMessage = "Please enter a Model Description.")]
      public string model_description { get; set; }
  
      [Required]
      [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
      public DateTime created_date { get; set; }
  
      [Required]
      public string created_by { get; set; }
  
      [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
      public DateTime? modified_date { get; set; }
  
      public string modified_by { get; set; }
  }
  </code></pre>
  
  <p>Can anyone spot what I'm doing incorrect on the <code>Include()</code>?</p>
  
  <hr>
  
  <p><strong>EDIT2</strong>:</p>
  
  <p>Thanks to <a href="https://stackoverflow.com/users/141172/eric-j">Eric J</a>'s suggestion, the issue is solved! Added a <code>ToString()</code> override on each of my desired Models to ensure the value came through instead of just the object type:</p>
  
  <pre><code>public class INV_Models
  {
  
      public override string ToString()
      {
          return this.model_description;
      }
  }
  
  public class INV_Manufacturers
  {
      public override string ToString()
      {
          return this.manufacturer_description;
      }
  }
  
  public class INV_Locations
  {
      public override string ToString()
      {
          return this.location_dept + "|" + this.location_room;
      }
  }
  
  public class INV_Vendors
  {
      public override string ToString()
      {
          return this.vendor_name;
      }
  }
  
  public class INV_Types
  {
      public override string ToString()
      {
          return this.type_description;
      }
  }
  
  public class INV_Statuses
  {
      public override string ToString()
      {
          return this.status_description;
      }
  }
  </code></pre>
  
  <p><strong>ExportController</strong>:</p>
  
  <pre><code>    [HttpPost]
      public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
      {
          ExcelPackage package = new ExcelPackage();
          var ws = package.Workbook.Worksheets.Add("TestExport");
  
          var exportFields = new List&lt;string&gt;();
          foreach (var selectedField in model.SelectedFields)
          {
              // Adds selected fields to [exportFields] List&lt;string&gt;
              exportFields.Add(model.ListOfExportFields.First(s =&gt; s.Key == selectedField).Value);
          }
  
          // Loops to insert column headings into Row 1 of Excel
          for (int i = 0; i &lt; exportFields.Count(); i++)
          {
              ws.Cells[1, i + 1].Value = exportFields[i].ToString();
          }
  
          var membersToShow = typeof(INV_Assets).GetMembers().Where(p =&gt; exportFields.Contains(p.Name)).ToArray();
  
          ws.Cells["A2"].LoadFromCollection(_db.INV_Assets.ToList(), false, TableStyles.None, BindingFlags.Default, membersToShow);
  
  
  
          var membersToShow = typeof(INV_Assets).GetMembers().Where(p =&gt; exportFields.Contains(p.Name)).ToArray();
  
          var memoryStream = new MemoryStream();
          package.SaveAs(memoryStream);
  
          string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
          string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  
          memoryStream.Position = 0;
          return File(memoryStream, contentType, fileName);
      }
  </code></pre>
  
  <p>And the output Excel file:</p>
  
  <p><img src="https://i.stack.imgur.com/DuZrc.jpg" alt="Excel3"></p>