2010-04-25 3 views
5

ОК, поэтому у меня есть строго типизированное представление «Сведения» клиента, которое принимает модель объекта Customer.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); 
} 

Все работает, как ожидалось!

Теперь на мой взгляд, «Подробности» Я хочу, чтобы заполнить таблицу с 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> 
<% } %> 

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

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'

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

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

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

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

Спасибо!

+0

Является ли ваше представление строго типизированным для 'IEnumerable '? Если это не так, возможно, поэтому вы не можете перечислить его, без этого хелперного кода. –

+0

Мое мнение строго типизировано для Inherits = "System.Web.Mvc.ViewPage " Возможно, я был недостаточно ясен, но в представлении приводятся данные о счете клиента. Клиент имеет любое количество Пространств, которое также должно отображаться на этой странице. Поэтому я не хочу просто список пространств, я хочу подробный просмотр учетной записи Клиента, включая пространства клиента. –

ответ

14

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

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

+0

Это сработало для меня. – Rob

+0

Это сработало для меня тоже, кажется, немой, что по умолчанию этого не происходит –

+0

Как этот ответ изменится с учетом веб-приложения ASP.Net MVC с использованием механизма просмотра Razor? – beaudetious

1

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

Вы можете наследовать 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>) 
    { 
+0

Для первого варианта: Как уже упоминалось в моем комментарии к моему первоначальному сообщению, я не просто просто просматриваю пробелы, но отображаю подробную информацию об объектной модели объекта Customer, где объектная модель Customer содержит EntitySet пробелов. Для второго варианта: я попробовал кастинг в инструкции foreach, однако я получаю следующую ошибку: «Невозможно неявно преобразовать тип« System.Data.Linq.EntitySet 'в' object '"- Я думаю, что использование подхода View Model - это путь, но я не хочу дублировать себя. –

1
  • Прежде всего с помощью просмотра моделей вместо прямого доступа к DTO - . (Использование Automapper для этого)

  • Во-вторых, сильно введите свои взгляды Посмотреть модели и в виде модели имеют IEnumerable или список, переданный в зрения, то вы можете перемещаться по нему

+0

Как я могу создать модель View без дублирования коллекции пространств? Я использую учебник NerdDinner в качестве шаблона, а пример модели View - это класс, который использует объектную модель Customer, а также добавляет дополнительные свойства для дополнения исходной модели, которая проходит. В этом случае я получаю EntitySet of Spaces, а также отдельную коллекцию IEnumerable . Можете ли вы указать мне в сторону ресурса, который объяснил бы правильный способ структурирования этой View Model? Спасибо! –

+0

Правило большого пальца состоит в том, что вся информация, которая вам нужна, будет отображаться в модели просмотра, которую вы передаете, поэтому эта модель представления является индивидуальной и будет заполнена данными от DTO или DTO. Если вы хотите передать IEnumerable, тогда модель представления будет иметь IEnumerable в нем –

1

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