【问题标题】:Get first item from each category从每个类别中获取第一项
【发布时间】:2020-11-03 13:51:40
【问题描述】:

我有 5 个类别:

书籍、DVD、租、买、卖

我使用以下查询来选择最新的项目数。

public async Task<IList<Post>> GetRecentPostsAsync(int count)
{
    return await _db.Posts
        .Where(e => e.Published.HasValue && e.Published.Value <= DateTime.Today)
        .OrderByDescending(e => e.Published)
        .Take(count)
        .ToListAsync();
}

我的 Post 类如下所示:

public class Post
{
    #region Properties

    [Key]
    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string Title { get; set; }

    [Required]
    [StringLength(25)]
    public string Category { get; set; }

    public DateTime? Published { get; set; }

    #endregion
}

这将返回我的项目数。我想创建一个新功能,从前 4 个类别中获取最近发布的项目,因此不包括类别 Sell。它应该返回 4 个项目。

我怎样才能做到这一点?

【问题讨论】:

  • minimal reproducible example,简单的类,表示带有类别的帖子。和初始化。您不需要 N 个类别,只需要超过 1 个,每个类别中有多个项目。

标签: c# linq linq-to-sql


【解决方案1】:

这应该会给您一个List&lt;Post&gt;,以及除“销售”之外的每个类别中最后发布的Post

return await _db.Posts
        .Where(x => x.Category != "Sell" && x.Published.HasValue && x.Published.Value <= DateTime.Today)
        .GroupBy(x => x.Category)
        .Select(x => x.OrderByDescending(x => x.Published).Take(1))
        .SelectMany(x => x)
        .ToListAsync();

【讨论】:

  • 正是我想要的。很好很简单。谢谢!
【解决方案2】:

没有立即理解这个问题。所以,试试吧。

public async Task<IList<Post>> GetRecentPostsAsync()
        {            
            List<string> categories = new List<string> { "Book", "DVD", "Rent", "Buy" };
            List<Post> result = new List<Post>();

            foreach (string category in categories)
            {
                Post post = db.Posts.Where(e => e.Published.HasValue && e.Published.Value <= DateTime.Today && e.Category == category)
                    .OrderByDescending(e => e.Published)
                    .Take(1).First();
                result.Add(post);
            }

            return result;
        }

【讨论】:

  • 现在需要 1 个项目。我需要它从每 4 个类别中提取 1 个项目,所以总共 4 个项目。
  • 按照 Krishna 的建议,您最好创建一个类别类或枚举
  • 您错过了类别 == e.category,但除此之外,它非常有效!我现在就试试 Krishna 的方法,但谢谢!
【解决方案3】:

试试这个。这将为您提供不包括销售的类别计数

public class PostCategory 
{
    public string Category { get; set; }
    public int Count { get; set; }
}

public async Task<IList<PostCategory>> GetRecentPostsAsync()
{
    return await _db.Posts
        .Where(e => e.Published.HasValue && e.Published.Value <= DateTime.Today && e.Category != "Sell")
        .GroupBy(x => x.Category)
        .Select(y => new { Category = y.Key, Count = y.Count() })
        .ToListAsync();
}

【讨论】:

  • 这似乎给了我错误“不能隐式转换类型 'System.Collections.Generic.List>' to 'System.Collections.Generic.IList <.model.domain.post>'。存在显式转换(您是否缺少演员表)?但是添加演员只会给我另一个错误
  • 是的,使用 Category 和 Count 创建一个新类并返回为列表
  • 好吧,我用字符串 Category 和 int Count 创建了一个新的域类 PostCategory。我如何在这个函数中使用它?
  • 更新了我的帖子
猜你喜欢
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 2021-05-29
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多