【问题标题】:advanced projection query高级投影查询
【发布时间】:2013-10-12 16:23:18
【问题描述】:

有什么更好的方法

using (var db = new SmartContext())
{
    var MyQuery = from idr in db.ID_SB
                  join tk in db.Track_SB on idr.MB_Track_ID equals tk.MB_TrackID
                  join talr in db.Track_Album_Reln on tk.MB_TrackID equals talr.MB_Track_ID
                  join tal in db.Album_SB on talr.MB_AlbumID equals tal.MB_Release_ID
                  orderby idr.Last_played descending
                  select new
                  {
                      mb = tk.MB_TrackID,
                      Hash = idr.Hash,
                      Title = tk.Title,
                      Album = tal.Album_Name,

                      Times_Played = idr.Times_played,
                      Last_Played = idr.Last_played

                  };

    string artist = "";
    var list = new[] { new {  Hash = "", Title = "", Album = "", Artist = "", Times_Played = "", Last_Played = ""}}.ToList();
    list.Clear();
    foreach (var q in MyQuery)
    {
        int i = 0;
        var art = db.Track_Artist_Reln.Where(a => a.MB_Track_ID == q.mb);
        foreach (var a in art)
        {
            var tart = db.Artist_SB.Where(ar => ar.MB_Artist_ID == a.MB_ArtistID).Select(ar => ar.Artist_Name);
            foreach (var tar in tart)
            { if (i != 0) { artist = artist + ", " + tar; } else { artist = tar; i++; } }
        }
        list.Add(new
        {
            Hash = q.Hash.ToString(),
            Title = q.Title.ToString(),
            Album = q.Album.ToString(),
            Artist = artist.ToString(),
            Times_Played = q.Times_Played.ToString(),
            Last_Played = q.Last_Played.ToString(),            
          });
    }


    ListView1.ItemsSource = list;
}

有没有更好的方法,因为它消耗大量时间

这段代码可以达到目的

在这我想检索

  • 散列
  • 标题
  • 专辑名
  • 艺术家(包含单行字段艺术家中该歌曲的所有艺术家)
  • 播放次数
  • 上次播放

我能得到的一切都是通过加入除了艺术家姓名之外的所有东西

有很多可能的关系 主表 ID_SB、Track_SB、Album_SB、Artist_SB 其他是存储两个表的主键的关系

【问题讨论】:

  • 一个快速的改进方法是将两个 foreach 循环中的嵌套 db 查询移动到主查询中,方法是在您的第一个查询中将其作为集合返回。这将导致它对数据库的访问次数减少很多。
  • 你也应该去掉 *_Reln 表,EF 多年来一直直接支持多对多关系。

标签: c# linq


【解决方案1】:

内部循环可以替换为使用string.Join(…).SelectMany() 将嵌套列表(实际上是IEnumerable)扁平化为一个:

var artist = string.Join(", ",
                         db.Track_Artist_Reln
                           .Where(a => a.MB_Track_ID == q.mb)
                           .SelectMany(a => db.Artist_SB
                                              .Where(ar => ar.MB_Artist_ID == a.MB_ArtistID)
                                              .Select(ar => ar.Artist_Name)));

您可以使用.ToList(),而不是手动将枚举转换为列表:

var list = MyQuery.Select(q => new{
        Hash = q.Hash.ToString(),
        Title = q.Title.ToString(),
        Album = q.Album.ToString(),
        Artist = string.Join(", ",
                             db.Track_Artist_Reln
                               .Where(a => a.MB_Track_ID == q.mb)
                               .SelectMany(a => db.Artist_SB
                                                  .Where(ar => ar.MB_Artist_ID == a.MB_ArtistID)
                                                  .Select(ar => ar.Artist_Name))),
        Times_Played = q.Times_Played.ToString(),
        Last_Played = q.Last_Played.ToString(),            
        }.ToList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多