用Dapper映射嵌套对象的列表

本文关键字:列表 对象 嵌套 Dapper 映射 | 更新日期: 2023-09-27 18:07:51

我使用的是Dapper,我有这样的类:

public class Article{
   public int Id { get; set; }
   public string Description{get;set;}
   public Group Group { get; set; }
   public List<Barcode> Barcode {get;set;}
   ...
}
public class Group{
   public int Id { get; set; }
   public string Description {get;set;}
}
public class Barcode{
   public int Id { get; set; }
   public string Code{get;set;}
   public int IdArticle { get; set; }
   ...
}

我可以得到关于文章的所有信息,但我想知道是否有可能用一个查询也得到每篇文章的条形码列表。实际上我是这样做的:

string query = "SELECT * FROM Article a " +
"LEFT JOIN Groups g ON a.IdGroup = g.Id ";
arts = connection.Query<Article, Group, Article>(query,
    (art, gr) =>
    { art.Group = gr;  return art; }
    , null, transaction).AsList();

我也在这里找到了一个很好的解释,但我不明白如何在我的情况下使用它,因为我也有Group类。我应该如何用Dapper做到这一点,它是可能的还是唯一的方法是做不同的步骤?由于

用Dapper映射嵌套对象的列表

QueryMultiple是你的朋友

var query = @"
select a.*, g.* from Article a left join Groups g on g.Id = a.IdGroup    
select * from Barcode";
//NOTE: IdGroup should exists in your Article class.
IEnumerable<Article> articles = null;
using (var multi = connection.QueryMultiple(query)){
    articles = multi.Read<Article, Group, Article>((a, g)=>
            { a.Group = g; return a; });
    if (articles != null) {
      var barcodes = multi.Read<Barcode>().ToList();
      foreach(var article in articles){           
        article.Barcode = barcodes.Where(x=>x.IdArticle == article.Id).ToList(); 
      }
    }
}

这可能不是很有趣,特别是如果您的查询中没有任何过滤器。但我怀疑你会归还所有的物品。在这种情况下,你可以像这样过滤条形码(编辑sql)>select * from Barcode where Id in @ids。然后在QueryMultiple中包含参数ids(文章id列表)。

Option2

或者你可以单独查询:

var query = "select a.*, g.* from Article a left join Groups g on g.Id = a.IdGroup";
var articles = connection.Query<Article, Group, Article>(query,
    (a,g)=> { a.Group = g; return g; }).ToList();
query = "select * from Barcode where IdArticle IN @articleIds";
var articleIds = articles.Select(x=>x.Id);
var barcodes = connection.Query<Barcode>(query, new { articleIds });
foreach(var article in articles){           
    article.Barcode = barcodes.Where(x=>x.IdArticle == article.Id);
}