ASP.NET MVC 3: использование методов расширения Enumerable в представлении

Учитывая следующее частичное представление Razor и понимание того, что Product является сопоставленным объектом NHibernate, поэтому вызовы IEnumerable здесь будут запускать запросы к базе данных (если они не кэшируются).

Это плохая практика? Должен ли я предоставлять более плоское представление моих данных для этого представления, чтобы я мог выполнять эти вызовы в своем контроллере/бизнес-логике?

@model IEnumerable<MyProject.Data.Models.Product>
<table>
    <tr>
        <th></th>
        <th>Total Orders</th>
        <th>Fulfilled</th>
        <th>Returned</th>
        <th>In stock</th>
    </tr>
    @foreach (var product in Model) { 
        <tr>
            <td>
                @Html.ActionLink(product .Name, "Detail", "Product", new { id = product.Id }, null)
            </td>
            <td>
                @product.Orders.Count
            </td>
            <td>
                @product.Orders.Where(x=>x.Fulfilled).Count()
            </td>
            <td>
                @product.Orders.Where(x=>x.Returned).Count()
            </td>
            <td>
                @(product.Stock.Count - product.Orders.Count)
            </td>
        </tr>
    }
</table>

person Rob Stevenson-Leggett    schedule 23.02.2011    source источник


Ответы (1)


Это плохая практика?

Да. На самом деле это нарушает шаблон MVC - представление не должно возвращаться через модель, а только получать, чтобы выполнять свою единственную работу: рендеринг HTML.

Если вам нужна дополнительная информация, а не только одна сущность, заполните ViewModel всей необходимой информацией, а затем передайте ее своему представлению.

Кроме того, не зацикливайтесь на IEnumerable в модели, используйте Шаблон отображения:

@Html.DisplayForModel()

Преимущество этого заключается в отсутствии явного цикла, использовании соглашений MVC и соблюдении иерархии модели при привязке модели.

person RPM1984    schedule 23.02.2011
comment
Это кажется простым прагматичным способом делать что-то, но я как бы знал, что это неправильно с точки зрения MVC. - person Rob Stevenson-Leggett; 23.02.2011
comment
Ага. всякий раз, когда вы начинаете писать код в своих представлениях, если это не @Html.<somehelper>, должны сработать тревожные звоночки, и вы должны реорганизовать свое представление/контроллер, чтобы упростить вещи. Поместите любую логику в свои ViewModels или Controller. - person RPM1984; 23.02.2011
comment
Нет ничего плохого в использовании foreach для прокрутки вашего IEnumberable из вашей модели, если он предназначен только для рендеринга логики рендеринга HTML. Помощники великолепны, но их использование не нарушает шаблон MVC. Однако (@product.Orders.Where(x=›x.Fulfilled).Count()) - person Steven Striga; 23.02.2011
comment
@WeekendWarrior - вы правы, нет ничего плохого в использовании foreach для циклического просмотра вашей модели, если он предназначен только для рендеринга HTML - но в этом случае он снова вызывает модель, что это то, что ломает шаблон. И даже основные циклы foreach, если вы можете их избежать, вам следует. Зачем писать код в представлениях, если этого можно избежать? - person RPM1984; 24.02.2011