Linq查询以限制分组

时间:2019-01-09 15:22:19

标签: c# linq

我有一个以下结构的简单表。

enter image description here

我想编写一个LINQ表达式以始终仅获取5条记录。如果可用,这5应该是“金”。否则,添加“ Bronze”以使其变为5。如果仍然不是5,则将“ Silver”添加到列表中。但是返回的总结果应该为5。就性能而言应该很好。

我尝试了基本的linq,但是没有运气。我们非常感谢您的帮助。

班级:

public class Option {
  public int Id {get;set;

  public string Name {get;set;}

  public string Priority {get;set;}
} 

dbContext.Options将通过ORM创建到数据库表的连接,我们可以在其中应用linq表达式。

尝试:dbContext.Options.OrderByDescending(o => o.Priority).GroupBy(a => a.Priority)

这将按优先级返回分组结果。但我想在此表达式中包含所需的逻辑。

5 个答案:

答案 0 :(得分:2)

您要为每个字符串分配一个排序值,以便对其进行排序。为此,您可以将整数0分配给金,将1分配给古铜,将2分配给银(其他)。

然后您使用Take来获取前5条记录。

// ordered by gold, bronze, silver

var result = dbContext.Options
    .OrderBy(o => o.Priority == "Gold" ? 0 : o.Priority == "Bronze" ? 1 : 2)
    .Take(5)
    .ToList();

答案 1 :(得分:1)

  

在性能方面应该很好。

然后,您可以考虑使用原始SQL来过滤针对数据库执行的原始查询中的记录,例如:

dbContext.Options.SqlQuery("SELECT TOP 5 * FROM [Option] ORDER BY CASE WHEN [Priority] = 'Gold' THEN 1 WHEN [Priority] = 'Bronze' THEN 2 WHEN [Priority] = 'Silver' THEN 3 ELSE 4 END").ToArray();

在查询数据库时,最高性能和LINQ很少并存。

答案 2 :(得分:1)

让Priority成为枚举,将其排序并取5。

        class Option
        {
            public int Id { get; set; }

            public string Name { get; set; }

            public Priority Priority { get; set; }
        }

        enum Priority
        {
            Gold = 0,
            Silver,
            Bronze
        }

        static void Main(string[] args)
        {
            var list = new List<Option>()
            {
                new Option { Id = 1, Name = "Bob", Priority = Priority.Gold },
                new Option { Id = 2, Name = "Rob", Priority = Priority.Gold },
                new Option { Id = 2, Name = "David", Priority = Priority.Bronze },
                new Option { Id = 2, Name = "Adam", Priority = Priority.Bronze },
                new Option { Id = 2, Name = "Jack", Priority = Priority.Silver },
                new Option { Id = 2, Name = "Josh", Priority = Priority.Silver },
                new Option { Id = 2, Name = "Peter", Priority = Priority.Silver },
                new Option { Id = 2, Name = "Max", Priority = Priority.Silver },
                new Option { Id = 2, Name = "Steve", Priority = Priority.Silver },
            };

            var newList = list.OrderBy(l => l.Priority).Take(5);
}

答案 3 :(得分:1)

List<Option> top5 = participants.OrderBy(part => {
    switch(part.Priority) {
        case "Gold": return 1;
        case "Bronze": return 2;
        case "Silver": return 3;
        default: return 4;
    }
}).Take(5).ToList();

如果列表短于5,则需要订购它们。

答案 4 :(得分:1)

请参见下面的代码:

            List<string> rank = new List<string>() { "Gold", "Bronze","Silver" };

            DataTable dt = new DataTable();

            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Priority", typeof(string));

            dt.Rows.Add(new object[] { 9, "Steve", "Silver" });
            dt.Rows.Add(new object[] { 8, "Max", "Silver" });
            dt.Rows.Add(new object[] { 7, "Peter", "Silver" });
            dt.Rows.Add(new object[] { 6, "Josh", "Silver" });
            dt.Rows.Add(new object[] { 5, "Jack", "Bronze" });
            dt.Rows.Add(new object[] { 4, "Adam", "Bronze" });
            dt.Rows.Add(new object[] { 3, "David", "Gold" });
            dt.Rows.Add(new object[] { 1, "Bob", "Gold" });
            dt.Rows.Add(new object[] { 2, "Rob", "Gold" });

           DataRow[] results = dt.AsEnumerable().OrderBy(x => rank.IndexOf(x.Field<string>("Priority"))).Take(5).ToArray();