【问题标题】:Linq counting second grouping and counting without groupinglinq计数二次分组和计数不分组
【发布时间】:2020-06-15 22:48:32
【问题描述】:

我正在尝试构建一个用于统计的摘要查询。

我有一个包含以下列的数据表(大约 18000 行):

Artist / Album / file_path (one for each song) / rating / 

每个艺术家有 1 个或多个专辑,其中包含歌曲,每首歌曲都有评分

我想得到以下结果:

对于每个艺人ID(比艺人名更可靠),专辑总数、歌曲总数、评分总数等于5。

Artist x / #album / #songs / #rating = 5 / song.first() //in song.first i have access to the file path, it can be any file path from the artist hence the first one.

我已经拉了几个小时的头发,但我无法获得每位艺术家的专辑数量:(这是我迄今为止一直在尝试的:

我有一个查询类:

  public class art_detail
    {
        public string artiste { get; set; }
        public string fp { get; set; } // the file_path
        public int nbr_album { get; set; }
        public int nbr_song { get; set; }
        public int nbr_rat5 { get; set; }
    }

这是我提出的查询:

            var result = from res in Globals.ds.Tables[0].AsEnumerable() // the table
           .GroupBy(x =>  new { art = x.Field<int>("Artist_ID"), alb = x.Field<string>("album") })
           .Select(x => new art_detail { artiste = x.Select(p =>p.Field<string>("artiste")).First(), fp = x.Select(p=>p.Field<string>("file_path")).First(), nbr_album = x.Key.alb.Count() })
           .OrderBy(x => x.artiste)
                  select res;

不幸的是,计数完全错误,我不知道如何获得评分 = 5 :(

感谢您的帮助!

编辑: 这是我让它工作的查询:

               var table = Globals.ds.Tables[0].AsEnumerable();
               var stats = table.GroupBy(x => x.Field<int>("Artist_ID"))
                .Select(x => new art_detail
                {
                     artiste = x.Select(p=>p.Field<string>("artiste")).First(),
                     nbr_album = x.Select(y => y.Field<string>("album")).Distinct().Count(),
                     fp = x.Select(y => y.Field<string>("file_path")).FirstOrDefault(),
                     nbr_song = x.Count(),
                     nbr_rat5 = x.Count(y => y.Field<int>("Rating") == 5)
                 });

比我想象的要简单:)

【问题讨论】:

  • 由于您是按艺术家和专辑分组的,因此一位艺术家和多张专辑将有多个元素。因此,您可能应该仅按艺术家分组,然后获取专辑数量等。
  • 如果你想报告每个艺术家的统计数据,你需要使用 GroupBy。因为这就是你正在做的事情。您正在对数据进行分组。如果您只是在寻找一位艺术家,那么您可以通过使用 where 语句和 SelectMany() docs.microsoft.com/en-us/dotnet/api/… 来避免分组

标签: c# winforms linq


【解决方案1】:

假设一个表的模式与这个类匹配:

public class Song
{
    public string ArtistID { get; set; }
    public string Album { get; set; }
    public string FilePath { get; set; }
    public int Rating { get; set; }
}

给定一个 LINQ 源,您有以下查询:

IQueryable<Song> table = /*insert source*/;
var stats = table.GroupBy(x => x.ArtistID);
                 .Select(x => new art_detail
                 {
                     artiste = x.Key,
                     nbr_album = x.Select(y => y.Album).Distinct().Count(),
                     nbr_song = x.Count(),
                     nbr_rat5 = x.Count(y => y.Rating == 5),
                 });

【讨论】:

  • 谢谢你,我让它与你的输入一起工作。将编辑我的问题以供将来参考:)
【解决方案2】:

我使用了头部编译查询,因为在这种情况下它对我来说似乎更容易理解:

示例模型:

public class Artist
{
    public string ArtistID { get; set; }
    public string Album { get; set; }
    public string FilePath { get; set; }
    public int Rating { get; set; }
    public int NumberOfSongs { get; set; }
}

为 Usher 和 Beyonce 创建一些虚拟记录:

//Usher
var artistOne = new Artist() 
{
    ArtistID = "Usher",
    Album = "Lit",
    FilePath = "dummy/path/here",
    Rating = 5,
    NumberOfSongs = 9
};
var artistTwo = new Artist() 
{
    ArtistID = "Usher",
    Album = "Sick",
    FilePath = "dummy/path/here",
    Rating = 5,
    NumberOfSongs = 11
};
var artistThree = new Artist() 
{
    ArtistID = "Usher",
    Album = "Dope",
    FilePath = "dummy/path/here",
    Rating = 4,
    NumberOfSongs = 14
};

//Beyonce
var artistFour = new Artist() 
{
    ArtistID = "Beyonce",
    Album = "Hot",
    FilePath = "dummy/path/here",
    Rating = 5,
    NumberOfSongs = 8
};
var artistFive = new Artist() 
{
    ArtistID = "Beyonce",
    Album = "Fire",
    FilePath = "dummy/path/here",
    Rating = 4,
    NumberOfSongs = 16
};

var listOfArtist = new List<Artist> { artistOne, artistTwo, artistThree, artistFour, artistFive };

运行查询:

var result =  from a in listOfArtist
              where a.Rating == 5
              group a by a.ArtistID into art
              select new
              {
                 artist = art.Key,
                 numberOfAlbums = art.Count(),
                 numberOfSongs = art.Sum(d => d.NumberOfSongs),
              }; 

结果:

希望这会有所帮助 =)

【讨论】:

  • 感谢可口可乐,我没能成功。我有两个问题: 1/ 我没有 NumberOfSongs 字段,但实际上每首歌曲只有一行。 2/ 我无法检索文件路径。但我设法使它与下面的 naasking 答案一起工作。我会用答案编辑我的问题。
猜你喜欢
  • 2014-09-07
  • 1970-01-01
  • 2013-07-19
  • 1970-01-01
  • 2016-08-08
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
  • 2015-05-29
相关资源
最近更新 更多