【问题标题】:entity framework - sort the rows(few records) in list实体框架 - 对列表中的行(几条记录)进行排序
【发布时间】:2018-10-05 11:53:34
【问题描述】:

我有一个距离升序排列的列表。

like需要从4到6排序

未排序:

但我想这样排序, 在以距离方式排序后,现在想要根据可用性对列表进行排序,如果插槽如下所示 仅对相同距离的记录进行排序。

id从4到6排序

排序:

有没有人可以解决这个问题?

【问题讨论】:

  • 我真的不明白你的排序逻辑...... - 为什么 ID=8 在最底部?为什么 ID=4,5,6 以它们的方式排序,应该应用什么逻辑来获得所需的结果 - 为什么正确的顺序 ID=5,6,4 - 我只是无法弄清楚那里的逻辑是?!?
  • EntityFramework 和 Linq 允许您使用可能满足您需求的自定义比较器。 collection.OrderBy(x => x.Distance>).ThenBy(y => y.SlotAvailability, yourComparer);
  • @Wokuo 可以举例说明吗?
  • @RandRandom 逻辑是,我想按照第二张图片对其他列进行排序。如果 3 条记录具有相同的距离值但插槽的可用性类型不同,则应将其排序为可用性“是”应该在这 3 条记录中排在第一位,然后是具有“未来”值的记录和具有“否”值的记录。
  • 只有当 3 个具有相同距离的记录彼此相邻时?所以如果在第一张图片上 ID = 5 不存在,它什么都不做?

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


【解决方案1】:

如果您真的只需要对完整列表中的数据块进行排序,那么我建议您使用以下方法之一将数据分组。

  1. LINQ query — Data aggregation (Group Adjacent)
  2. LINQ query to split an ordered list into sublists of contiguous points by some criteria
  3. (推荐解决方案)https://github.com/morelinq/MoreLINQ/blob/master/MoreLinq/GroupAdjacent.cs https://www.nuget.org/packages/morelinq/

对于以下示例,我使用了第一个链接中所述的GroupAdjacent

就这样吧:

//class for test data
public class Data
{
    public int    Id               { get; set; }
    public int    Distance         { get; set; }
    public string SlotAvailability { get; set; }

    public override string ToString()
    {
        return $"ID={Id} | Distance={Distance} | SlotAvailability={SlotAvailability}";
    }
}

class Program
{
    static void Main(string[] args)
    {
        //test data
        var lst = new List<Data>()
        {
            new Data() {Id = 1, Distance = 5, SlotAvailability  = "yes"},
            new Data() {Id = 2, Distance = 6, SlotAvailability  = "yes"},
            new Data() {Id = 3, Distance = 8, SlotAvailability  = "no"},
            new Data() {Id = 4, Distance = 9, SlotAvailability  = "no"},
            new Data() {Id = 5, Distance = 9, SlotAvailability  = "yes"},
            new Data() {Id = 6, Distance = 9, SlotAvailability  = "in future"},
            new Data() {Id = 7, Distance = 11, SlotAvailability = "in future"},
            new Data() {Id = 8, Distance = 9, SlotAvailability  = "in future"},
        };

        //group the results into chunks
        var groupedList = lst.GroupAdjacent(x => x.Distance)

        //apply the sort logic - this assumes that you only want to sort if there are more or equals to 3 items in the group
        var sortedList = groupedList.SelectMany(x =>
        {
            if (x.Count() < 3) //if the count of the group is below 3 return it as it is
                return x.AsEnumerable();

            //if the Count is greater or equals to 3 sort the Group by SlotAvailability
            return x.OrderBy(y =>
            {
                switch (y.SlotAvailability)
                {
                    case "yes":
                        return 1;
                    case "in future":
                        return 2;
                    case "no":
                        return 3;

                    default:
                        return 0;
                }
            });
        });

        //print result
        foreach (var data in sortedList)
            Console.WriteLine(data);

        //wait for user input
        Console.ReadKey();
    }
}

如果您不希望在有 3 个或更多项目的情况下应用 SlotAvailability 排序逻辑而不是使用它

var sortedList = groupedList.SelectMany(x => x.OrderBy(y =>
    {
        switch (y.SlotAvailability)
        {
            case "yes":
                return 1;
            case "in future":
                return 2;
            case "no":
                return 3;

            default:
                return 0;
        }
    }));

【讨论】:

  • 嗨,兰德随机,感谢您的帮助。好的,这里我的列表略有变化。 slotavailability 本身是一个列表,其中一个名为“slot type”的属性的值可能是“yes”或“no”或“in future”,你能按照这个编辑你的答案吗?
  • 是的,我可以编辑它吗 - 但我有一个问题 - 因为 SlotAvailability 是一个列表 - 如果该列表在 SlotType 属性中有多个具有不同值的条目会发生什么? - 还是应该忽略这些情况,只检查列表中的第一个条目?
  • slottype 具有不同的值,“未来”或“无插槽”或插槽时间(在我的工作要求中)。实际上你上面的代码对我来说很完美,我只是根据要求在我的工作中改变了它。非常感谢您的回复。它完美无缺。 :)
  • 没问题,很高兴能帮上忙。
【解决方案2】:

好的,我在这里假设您对SlotAvailability 的值是我们在表中看到的字符串。您可以权重 OrderBy 语句,以确保按照您的需要按yes, in future, no 排序。

结果将是您按Distance 升序然后按您的加权SlotAvailability 值(也是升序)对记录进行排序。

我还假设您只有 SlotAvailability 可能的这 3 个值

例如:

.OrderBy(n=&gt;n.Distance).ThenBy(n=&gt;n. SlotAvailability == "yes" ? 1 : (n. SlotAvailability == "no" ? 3 : 2));

如您所见,我是这样分配权重(以及顺序)的:

  • 1 = 是
  • 2 = 未来
  • 3 = 否

【讨论】:

  • 这不会产生 OP 在他的第二张图片中显示的结果 - 因为它还会重新排列 ID=8 的条目。 ID=8 将介于 ID=6 和 ID=4 之间。
  • 嗨 Rand - 我假设(我知道这可能是我的失败)OP 实际上确实打算这样做。如果我错了,我会很高兴地羞愧地低下头并扣除一些开发者荣誉积分!
  • 是的,我也假设它 - 这就是我要求在 cmets 中澄清的原因 - 遗憾的是,OP 在他的回复中没有完全解释 ID=8 的情况。 :(
  • 在 OP 方面可能是一个诚实的错字/错误......或者......投票即将到来
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多