c# - Linq 排序的一些改进

标签 c# performance linq

我有以下记录

enter image description here

最后 2 个是记录 3 和 4 的子记录,我希望能够按金额对记录进行排序,但应该首先对兴趣( parent )记录进行排序,然后再对他们的记录进行排序 children 应该在之后出现,例如它会像这样

2000
2000
20001
99.84 (child of the above)
50000
249.58 (child of the above)

基本上,我希望按金额排序忽略“IsInterest”设置为 true 的排序,但让它们显示在其父级之后。

我可以通过首先将所有父级放入一个新集合中来做到这一点..然后遍历父级以查看是否有任何子级,然后将它们插入到新集合中的父级之后,但我觉得这既不高效又肮脏代码所以我想我会问也许有人知道黑魔法。 排序还应该注意金额的升序/降序。

如果有帮助的话,我可以发布将集合分开并将其组合在一起的代码,但如果可能的话,我会尽量不使用该代码。

如果有帮助的话,我的排序方法采用“升序”或“降序”字符串

谢谢

更新2 我要指出的是,只会有 2 个级别,并且 children 将只有一位 parent (没有祖 parent ),并且每个 parent 最多有 1 个 child

更新代码(字段名称可能与数据库字段不同..)

 switch (sortMember.ToUpper())
            {
                case "AMOUNT":
                    {
                        //check to see if any imputed interests exist
                        if (contributions.Any(x => x.IsImputedInterest))
                        {
                            var children = contributions.Where(x => x.IsImputedInterest);
                            var sortedColl = contributions.Where(x => x.IsImputedInterest == false).OrderByWithDirection(x => x.ContributionAmount, sortDirection.ToUpper() == "DESCENDING").ToList();
                            foreach (var child  in children )
                            {
                                //find the parent
                                var parentIndex = sortedColl.FindIndex(x => x.ContributionId == child.ParentContirbutionId);
                                sortedColl.Insert(parentIndex+1, child);

                            }

                        }
                        else
                        {
                            contributions = contributions.OrderByWithDirection(x => x.ContributionAmount, sortDirection.ToUpper() == "DESCENDING");
                        }

                        break;
                    }
            }

........................

 public static IOrderedEnumerable<TSource> OrderByWithDirection<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, bool descending)
    {
        return descending ? source.OrderByDescending(keySelector)
                          : source.OrderBy(keySelector);
    }

    public static IOrderedQueryable<TSource> OrderByWithDirection<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool descending)
    {
        return descending ? source.OrderByDescending(keySelector)
                          : source.OrderBy(keySelector);
    }

最佳答案

这是一个单语句 Linq 解决方案:

var desc = order == "descending";
var result = list
    //group parents with it's children
    .GroupBy(x => x.ParentId ?? x.Id)
    //move the parent to the first position in each group
    .Select(g => g.OrderBy(x => x.ParentId.HasValue).ThenBy(x => desc ? -x.Amount : x.Amount))
    //sort the groups by parents' amounts
    .OrderBy(g => desc ? -g.First().Amount : g.First().Amount)
    //retrieve the items from each group
    .SelectMany(g => g);

一些性能提示:

  • 如果总是最多有一个 child 或者您不关心 child 的顺序,您可以删除 ThenBy(...)
  • 使用 if 语句检查顺序,并有两个版本的语句 - 第二个版本使用 OrderByDescending/ThenByDescending,然后删除三元运算符 (desc ? ... : ...) - 否则将为每个项目进行评估

对于与您当前的解决方案相关的性能,我不提供任何保证 - 它可能会变得更慢。

关于c# - Linq 排序的一些改进,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33067028/

相关文章:

c# - 动态 where 子句的最简单方法

c# - 在 Xamarin Android 中,AssemblyInfo.cs 与 AndroidManifest.xml 有何关系?

c# - 具有 TrulyObservableCollection 的 WPF Datagrid 失去了对编辑的关注

c# - NHibernate 3.2 按代码 (Conformist) 字典属性的类映射

java - 可以从命令行检索 jconsole 数据吗?

sql-server - 除了 MS Profiler 之外,还有哪些工具可用于分析 SQL Server 中的存储过程?

php - MySQL 分析显示查询时间比 PHP 微时差慢

linq - 复杂的 LINQ 或 EF 查询

c# - 如何在具有一个不同值的列表中查找相同的类

c# - Linq 返回实体中的所有记录,其中字段包含列表中的一个或多个单词