ASP.NET MVC/LINQ: What's the proper way to iterate through a Linq.EntitySet in a View?

Jeff Camera picture Jeff Camera · Apr 26, 2010 · Viewed 7.3k times · Source

OK so I have a strongly-typed Customer "Details" view that takes a Customer object Model.

I am using LINQ to SQL and every Customer can have multiple (parking) Spaces.

This is a FK relationship in the database so my LINQ-generated Customer model has a "Spaces" collection. Great!

Here is a code snippet from my CustomerRepository where I iterate through the Customer's parking spaces to delete all payments, spaces and then finally the customer:

public void Delete(Customer customer)
{
    foreach (Space s in customer.Spaces)
        db.Payments.DeleteAllOnSubmit(s.Payments);
    db.Spaces.DeleteAllOnSubmit(customer.Spaces);
    db.Customers.DeleteOnSubmit(customer);
}

Everything works as expected!

Now in my "Details" view I want to populate a table with the Customer's Spaces:

<% foreach (var s in Model.Spaces)
   { %>
    <tr>
        <td><%: s.ID %></td>
        <td><%: s.InstallDate %></td>
        <td><%: s.SpaceType %></td>
        <td><%: s.Meter %></td>
    </tr>
<% } %>

I get the following error:

foreach statement cannot operate on variables of type 'System.Data.Linq.EntitySet' because 'System.Data.Linq.EntitySet' does not contain a public definition for 'GetEnumerator'

Finally, if I add this bit of code to my Customer partial class and use the foreach in the view to iterate through ParkingSpaces everything works as expected:

public IEnumerable<Space> ParkingSpaces
{
    get
    {
        return Spaces.AsEnumerable();
    }
}

The problem here is that I don't want to repeat myself. I was also thinking that I could use a ViewModel to pass a Spaces collection to the View, however LINQ already infers and creates the Spaces property on the Customer model so I think it would be cleanest to just use that.

I am missing something simple or am I approaching this incorrectly?

Thanks!

Answer

Alastair Hopkins picture Alastair Hopkins · May 20, 2010

Sorry if Im a bit late answering this but the correct method of solving your problem is to add an assembly reference to your web.config file so that the view can access the GetEnumerator() method. You can do this using the assembly reference string provided in the page compliation error. eg

<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>