您如何按 ICollection 的属性进行排序
本文关键字:排序 属性 何按 ICollection | 更新日期: 2023-09-27 18:35:33
我正在尝试找出对模型参数ICollection
的显示或LINQ调用。具体来说,这是我的PurchReq
(采购申请)模型:
public enum FiscalYear
{
[Display(Name="2013")]
LastYear,
[Display(Name="2014")]
ThisYear,
[Display(Name="2015")]
NextYear
}
public class PurchReq
{
[Key]
public int PurchReqID { get; set; }
[Display(Name="Fiscal Year")]
public FiscalYear FiscalYear { get; set; }
//[ForeignKey("Project")]
//public int ProjectID { get; set; }
[Required]
[Display(Name="Purchase Requisition Number")]
public string PurchReqNum { get; set; }
public string GLCode { get; set; }
public string Fund { get; set; }
public string Division { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Purch Req Created")]
public DateTime? DateCreated { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Purch Req Submitted")]
public DateTime? DateSubmitted { get; set; }
//many projects to many purchReqs
//public virtual Project Project { get; set; }
public virtual ICollection<Project> Projects { get; set; }
public PurchReq()
{
DateCreated = System.DateTime.Now;
Projects = new HashSet<Project>();
}
这是我的索引方法的PurchReqController:
var purchReqs = from p in db.PurchReqs
select p;
if (!string.IsNullOrEmpty(searchString))
{
purchReqs = purchReqs.Where(s => s.Projects.Any(item => item.Vendor.VendorName.Contains(searchString)));
}
switch (sortOrder)
{
case "ProjectName_desc":;
purchReqs = purchReqs.OrderByDescending(s => s.Projects);
//Any(item => item.Vendor.VendorName).ThenBy(n => n.Project.Description));
break;
case "PurchReqNum_desc":
purchReqs = purchReqs.OrderByDescending(s => s.PurchReqNum);
break;
case "PurchReqNum_asc":
purchReqs = purchReqs.OrderBy(s => s.PurchReqNum);
break;
case "FiscalYear_desc":
purchReqs = purchReqs.OrderByDescending(s => s.FiscalYear);
break;
case "FiscalYear_asc":
purchReqs = purchReqs.OrderBy(s => s.FiscalYear);
break;
case "GLCode_desc":
purchReqs = purchReqs.OrderByDescending(s => s.GLCode);
break;
case "GLCode_asc":
purchReqs = purchReqs.OrderBy(s => s.GLCode);
break;
case "Fund_desc":
purchReqs = purchReqs.OrderByDescending(s => s.Fund);
break;
case "Fund_asc":
purchReqs = purchReqs.OrderBy(s => s.Fund);
break;
case "Division_desc":
purchReqs = purchReqs.OrderByDescending(s => s.Division);
break;
case "Division_asc":
purchReqs = purchReqs.OrderBy(s => s.Division);
break;
case "DateCreated_desc":
purchReqs = purchReqs.OrderByDescending(s => s.DateCreated);
break;
case "DateCreated_asc":
purchReqs = purchReqs.OrderBy(s => s.DateCreated);
break;
case "DateSubmitted_desc":
purchReqs = purchReqs.OrderByDescending(s => s.DateSubmitted);
break;
case "DateSubmitted_asc":
purchReqs = purchReqs.OrderBy(s => s.DateSubmitted);
break;
default:
purchReqs = purchReqs.OrderBy(s => s.Projects);
//purchReqs = purchReqs.OrderBy(s => s.Projects.Any(item => item.Vendor.VendorName)).ThenBy(n => n.Project.Description);
break;
}
return View(purchReqs);
上面的控制器抛出 DbSort 错误,因为它无法对 ICollection 项目进行排序,这是可以理解的。我需要按 Projects.Project.Vendor.VendorName 对集合进行排序。这最初在 PurchReq to Project 是多对一时有效,但最近已更改为多对多。任何建议和帮助将不胜感激。
试试这个:
purchReqs = purchReqs.OrderBy(pr => pr.Projects.Count > 0 ? pr.Projects.First().Vendor.VendorName : "")
.ThenBy (pr => pr.Projects.Count > 0 ? pr.Projects.First().Description : "");
这里我们使用First
而不是Any
;它给了我们一些合适的元素(当然,这并不重要,但Any
只是给了我们一个布尔值,没有其他特定的元素可以让我们半随机选择一个)。
在 C# 6 中,我认为您可以使用 null 传播成员访问运算符执行以下操作:
purchReqs = purchReqs.OrderBy(pr => pr.Projects.FirstOrDefault()?.Vendor?.VendorName)
.ThenBy (pr => pr.Projects.FirstOrDefault()?.Description);
无论哪种方式,都对两个排序调用使用相同的结构,假设Project
具有 Description 属性。
我知道我在这个线程上超级晚了,而且不是 MVC 方面的专家,但据我对排序集合的理解,它的工作原理是获取一个值并将其与同一列中的另一个值进行比较。基本上,您需要从所需的集合中选择一个字段并将其提供给 OrderBy lambda。
尽可能简单,它变得像这样:
IQueryable purchReq = context.PurchReq.OrderBy(p => p.Projects.Select(pj => pj.Project).FirstOrDefault().Select(v => v.Vendor.VendorName).FirstOrDefault());
如果项目与供应商也有 1 到 n 的关系,请替换
Select(v => v.Vendor.VendorName);
由
Select(v => v.Vendor).FirstOrDefault().VendorName
希望这有帮助。