ASP.NET MVC/LINQ: как правильно перебирать Linq.EntitySet в представлении?

Итак, у меня есть строго типизированное представление "Сведения" о клиенте, которое принимает объектную модель "Клиент".

Я использую LINQ to SQL, и каждый клиент может иметь несколько мест для парковки.

Это отношение FK в базе данных, поэтому моя модель Customer, созданная LINQ, имеет коллекцию "Spaces". Большой!

Вот фрагмент кода из моего CustomerRepository, где я перебираю парковочные места Клиента, чтобы удалить все платежи, пробелы и, наконец, клиента:

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);
}

Все работает как положено!

Теперь в моем представлении "Детали" я хочу заполнить таблицу пространствами клиента:

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

Я получаю следующую ошибку:

Оператор foreach не может работать с переменными типа "System.Data.Linq.EntitySet", поскольку "System.Data.Linq.EntitySet" не содержит открытого определения "GetEnumerator".

Наконец, если я добавлю этот фрагмент кода в свой частичный класс Customer и использую foreach в представлении для итерации по ParkingSpaces, все будет работать как положено:

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

Проблема в том, что я не хочу повторяться. Я также подумал, что мог бы использовать ViewModel для передачи коллекции Spaces в View, однако LINQ уже выводит и создает свойство Spaces в модели Customer, поэтому я думаю, что было бы чистым использовать это.

Я упускаю что-то простое или неправильно подхожу к этому?

Спасибо!

4 ответа

Решение

Извините, если я немного опоздал, отвечая на этот вопрос, но правильный метод решения вашей проблемы - добавить ссылку на сборку в ваш файл web.config, чтобы представление могло получить доступ к методу GetEnumerator(). Вы можете сделать это, используя справочную строку сборки, указанную в сообщении об ошибке компоновки страницы. например

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

Есть два способа сделать это, кроме вашего маленького вспомогательного метода.

Вы можете наследовать IEnumerable вашего класса на странице:

<%@ Page Language="C#"
    Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Space>>" %>

<% foreach (var item in Model)
   {

Или вы можете привести ваш объект сущности к IEnumerable:

<% foreach (var item in Model.Spaces as IEnumerable<Space>)
   {

Просто добавьте ссылку на System.Data.Linq к вашему проекту.

  • Прежде всего, предпочтительнее использовать View Models вместо прямого доступа к DTO. (используйте Automapper для этого)

  • Во-вторых, строго введите ваши представления в View Model, и в View View есть IEnumerable или List, передаваемый представлению, затем вы можете выполнить итерацию по нему.

Другие вопросы по тегам