C# MVC5 EF6中如何排序News集合及其子集合NewsComment?
问题解决:News子集合NewsComment排序无效的修复
核心问题原因
你当前代码里的news.ForEach(x => x.NewsComments.OrderByDescending(z => z.Date).ThenBy(d => DateTime.Now))不会生效,因为Linq的OrderBy系列方法是返回一个新的排序后的集合,而不是直接修改原集合。你只是调用了排序方法,但没有把排序后的结果重新赋值给x.NewsComments。
另外,你给News排序时的ThenBy(x => DateTime.Now.ToString())完全多余——DateTime.Now是固定值,这一步排序不会改变任何顺序,直接删掉即可。
修复方案
方案一:内存中排序并赋值
直接将排序后的集合重新赋值给NewsComments属性:
public ActionResult Index() { var news = db.News.ToList(); // 排序NewsComments并重新赋值 news.ForEach(x => x.NewsComments = x.NewsComments.OrderByDescending(z => z.Date).ToList()); HomeView homeView = new HomeView() { // 优化News排序:去掉无意义的ThenBy News = news.OrderByDescending(x => DateTime.Parse(x.Date)).ToList(), GameServerNodes = db.GameServerNodes.Where(x => x.Visible == 1).ToList(), GameServerTypes = db.GameServerTypes.OrderBy(x => x.Name).ToList(), GameServersCount = db.GameServers.Count() }; ViewBag.IsAdmin = steamAuthentication.IsAdmin(HttpContext); return View(homeView); }
方案二:EF查询时直接包含并排序子集合(更高效)
如果NewsComments是EF的导航属性,建议在查询News时就加载并排序子集合,避免后续在内存中二次处理:
public ActionResult Index() { // 一次性查询News并排序子集合,减少内存操作 var news = db.News .Select(n => new { News = n, SortedComments = n.NewsComments.OrderByDescending(c => c.Date).ToList() }) .ToList() .Select(x => { x.News.NewsComments = x.SortedComments; return x.News; }) .ToList(); HomeView homeView = new HomeView() { News = news.OrderByDescending(x => DateTime.Parse(x.Date)).ToList(), GameServerNodes = db.GameServerNodes.Where(x => x.Visible == 1).ToList(), GameServerTypes = db.GameServerTypes.OrderBy(x => x.Name).ToList(), GameServersCount = db.GameServers.Count() }; ViewBag.IsAdmin = steamAuthentication.IsAdmin(HttpContext); return View(homeView); }
额外建议
- 把
News实体的Date字段类型从string改成DateTime,避免每次排序都要调用DateTime.Parse,既影响性能又可能出现格式解析错误。 - 如果使用EF Core,还可以用
Include结合ThenBy的方式直接在查询中排序导航属性(EF6不支持直接在Include里排序,所以用方案二的投影方式)。
内容的提问来源于stack exchange,提问作者Thomas Caiazzo
相关产品推荐
相关产品推荐

