使用Dapper映射嵌套对象的列表

9

我正在使用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来实现这一点,是否可能还是唯一的方法是执行不同的步骤?谢谢

1个回答

4

QueryMultiple is your friend

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)。

选项2

或者您可以只执行单独的查询:

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);
}

我更喜欢第一种选择。

嗨von,第二个选项中的行'var articleIds = articles.Select(x=>x.Id);'无法选择出现错误消息。如果不可能,你是如何做到的? - puti26
我不是100%确定,但我知道如果SELECT没有结果,Dapper会返回一个空列表。因此,.Select(expression)不应该抛出空异常。你遇到了什么错误? - von v.
代码中的articles是一个IEnumerable对象。如果你使用了using System.Linq,那么可以使用.Select来操作它。 - von v.
哦,我忘记检查“using System.Linq;”了。现在它可以工作了!谢谢。 - puti26
很高兴为您服务 ;) - von v.
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接