如何在 MVC 中对相关数据的集合进行排序?

How do I sort collection of related data in MVC?

我是MVC的新手,所以请温柔点。

这是我的数据设置方式; 我有一份订单清单 table。然后每个订单都有一个步骤列表,用于在不同的 table 中完成该订单,这些 table 具有一对多关系。

在我的订单索引页面上,我列出了所有有效订单。在详细信息页面上,我想列出该订单的每个步骤。我 运行 遇到的问题是步骤并不总是按 table 顺序排列。每个步骤都有一个步骤编号,用于确定它在步骤序列中的位置,但它不是键值。

我想我遗漏了一些简单的东西。

在此先感谢您的帮助。

这是我正在使用的东西;

OR_ORDER.cs

public partial class OR_ORDER
{
    public OR_ORDER()
    {
        this.OR_OP = new HashSet<OR_OP>();
    }

    public decimal NO { get; set; }
    public Nullable<decimal> MUSTERNO { get; set; }
    public Nullable<decimal> PRONO { get; set; }
    public Nullable<decimal> GRPNO { get; set; }
    public string NAME { get; set; }
    public string DESCR { get; set; }
    public string IDENT { get; set; }
    public Nullable<decimal> PPARTS { get; set; }
    public Nullable<decimal> SEQNO { get; set; }
    public Nullable<decimal> SOURCE { get; set; }
    public decimal STATUS { get; set; }

    public virtual ICollection<OR_OP> OR_OP { get; set; }
}

OR_OP.cs

public partial class OR_OP
{
    public decimal NO { get; set; }
    public decimal ORNO { get; set; }
    public string NAME { get; set; }
    public string DESCR { get; set; }
    public Nullable<decimal> APARTS { get; set; }
    public Nullable<decimal> ATE { get; set; }
    public Nullable<decimal> ATOTAL { get; set; }
    public Nullable<decimal> AWPLACE { get; set; }
    public Nullable<decimal> BPARTS { get; set; }
    public decimal CFLAG { get; set; }
    public Nullable<System.DateTime> CHTIME { get; set; }
    public Nullable<decimal> CPCOST { get; set; }
}

控制器中的详细操作

    public ActionResult Details(decimal id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        OR_ORDER or_order = db.OR_ORDER.Find(id);

        //or_order.OR_OP = or_order.OR_OP.OrderBy(s => s.NAME);

        if (or_order == null)
        {
            return HttpNotFound();
        }
        return View(or_order);
    }

终于Detials.cshtml查看

@model Scheduler.Models.OR_ORDER

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
<h4>JOB: @Model.NAME</h4>
<h4>@Model.DESCR</h4>
<hr />
<table>
    <tr>
        <th width="150px">
            Description
        </th>
        <th width ="150px">
            Time
        </th>
        <th width="150px">
            Op Info
        </th>
    </tr>

        @foreach (var item in Model.OR_OP)
        {                
            <tr>
                <td width="150px">
                    @Html.DisplayFor(modelitem => item.DESCR)
                </td>
                <td width="150px">
                    @Html.DisplayFor(modelitem => item.PTE)
                </td>
                <td width="150px">
                    @Html.DisplayFor(modelitem => item.OPINFO)
                </td>
            </tr>
        }

    </table>
</div>
<p>
    @*Html.ActionLink("Edit", "Edit", new { id = Model.NO }) |*@
    @Html.ActionLink("Back Job List", "Index")
</p>

根据您提供给我们的代码,最简单(侵入性最小)的方法是向模型添加 LINQ 表达式:

@foreach (var item in Model.OR_OP.OrderBy(c => c.NO)) // I wasn't sure what
                                                      // property to use

但是,在您的模型中使用该逻辑有点混乱。

您还可以将 属性 类型从 HashSet<OR_PP> 调整为 List<OR_OP>,如果您有 IComparer,则调用 List<>.Sort(),或者只使用什么您已经使用与我所做的相同的 LINQ 调用进行了注释,并且 .ToList() 它。

最好的解决方案,尽管不是非常漂亮,可能是添加另一个 class,它有一个额外的 属性 用于这个排序的集合。您将在两个 class 之间拥有冗余数据,但这是所有选项中最易于维护的。

您的评论行的问题是 HashSet<> 未排序。它们必须在实践中,因为 RAM 是,因此它们每次都会以相同的顺序枚举,但理论上,任何顺序都不能保证。但是,List<> 确实支持排序,它还实现了 ICollection<T>,这是 EF 集合属性的要求。


在你发表评论后,听起来你有一个更基本的问题——听起来你的操作是以字符串形式存储的。

快速解决这个问题的方法是按解析排序。

@foreach (var item in Model.OR_OP.OrderBy(c => int.Parse(c.NO))) // I wasn't sure what
                                                                 // property to use

那是糟糕。不要这样做,除非你,即使你有,也使用视图模型。

真的,您应该更改数据库和 属性 的类型。

这就是所谓的"Learning a lesson the hard way"。您看到的大多数示例代码只是将您的实体从 entity framework 直接发送到视图。这个问题很多。

首先,正如您所发现的那样,您无法通过这种方式真正控制实体模型的其他部分。例如,您不能轻易地告诉模型对导航 属性 进行排序。至少在这一点上不是。

其次,您还坚持将视图与数据模型紧密耦合,并且您的视图可能不具有完全相同的结构。

第三,您的视图和数据模型之间可能存在安全或验证差异。

最终,你想要的是一个视图模型。这是一个根据视图的需要量身定制的模型,仅包含视图所需的数据。您现在可以以任何格式、结构、顺序或任何您想要的方式将数据复制到该 ViewModel。

另一种方法是在视图中执行排序逻辑,这对某些人来说可能是可以接受的。我不这么认为。