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>)
{
Прежде всего, предпочтительнее использовать View Models вместо прямого доступа к DTO. (используйте Automapper для этого)
Во-вторых, строго введите ваши представления в View Model, и в View View есть IEnumerable или List, передаваемый представлению, затем вы можете выполнить итерацию по нему.