Linq在查询中排序子项

时间:2011-06-23 02:42:07

标签: c# linq entity-framework asp.net-mvc-3 razor

我有一个EF模型如下:

enter image description here

在这个模型上,我显然可以使用Categories.Products来接收产品列表。

我有一个查询如下,以返回一个类别列表,其中Products作为要在ASP.NET MVC 3视图中使用的列表:

var categories = (from a in context.Categories.Include("Products")
                  orderby a.SortOrder ascending
                  select a).ToList();
return View(categories);

为了按照SortOrder的顺序显示产品,我目前必须这样做:

<ul>
@foreach (var category in Model)
{
    <li>@category.Title
        <ul>
        @foreach (var product in category.Products.OrderBy(a => a.SortOrder))
        {
            <li>@product.Description</li>
        }
        </ul>
    </li>
}
</ul>

违规行是:@foreach (var product in category.Products.OrderBy(a => a.SortOrder)),因为这是在视图中处理我的一些模型。

有没有办法在查询中对此进行排序?

1 个答案:

答案 0 :(得分:8)

  

有没有办法在查询中对此进行排序?

查看模型当然:

public class CategoryViewModel
{
    public string Title { get; set; }
    public IEnumerable<ProductViewModel> Products { get; set; }
}

public class ProductViewModel
{
    public string Description { get; set; }
}

并在您的控制器操作中执行填充此视图模型所需的操作:

public ActionResult Index()
{
    var categories = 
        (from category in context.Categories
         orderby category.SortOrder ascending
         select new CategoryViewModel
         {
             Title = category.Title,
             Products = category
                 .Products
                 .OrderBy(p => p.SortOrder)
                 .Select(p => new ProductViewModel
                 {
                     Description = p.Description
                 })
             }).ToList(); 
        ).ToList();
    return View(categories);
}

Index.cshtml视图中,您可以摆脱丑陋的循环并使用显示模板:

@model IEnumerable<CategoryViewModel>
<ul>
    @Html.DisplayForModel()
</ul>

并在类别(~/Views/Shared/CategoryViewModel.cshtml

的显示模板中
@model CategoryViewModel
<li>
    @Html.DisplayFor(x => x.Title)
    <ul>
        @Html.DisplayFor(x => x.Products)
    </ul>
</li>

并在产品的显示模板内(~/Views/Shared/ProductViewModel.cshtml

@model ProductViewModel
<li>
    @Html.DisplayFor(x => x.Description)
</li>

作为对控制器操作的进一步改进,您可以使用AutoMapper在域模型(EF对象)和应传递给视图的视图模型之间进行映射。