使用 dapper c# 填充列表对象

Posted

技术标签:

【中文标题】使用 dapper c# 填充列表对象【英文标题】:Fill list object using dapper c# 【发布时间】:2013-06-28 10:05:43 【问题描述】:

我的数据库中有两个这样的表:

我有这个课程:

   class Ean
   
        public string Code get; set; 
   

   class Article
   
        public int Id  get; set; 
        public string Name  get; set; 
        public List<Ean> BarCode  get; set; 
   

List<Article> arts = new List<Article>();

我创建一个文章列表,并使用 dapper 进行查询。我想在这个列表中填写文章的名称,还想填写相关 ean 文章的列表。我尝试做这个查询:

SELECT ART.ID AS ID, ART.NAME AS NAME,EAN.EAN AS BARCODE
FROM ART,EAN
WHERE ART.ID = EAN.ID_ART;

在c#中..

arts = conn.Query<Article>(query, null, transaction).ToList();

但不工作。我该怎么办?谢谢..欢迎任何建议。

【问题讨论】:

您将无法一口气做到这一点。见***.com/questions/7508322/… 从外观上看,您应该在这里使用内部联接,而不是交叉联接。 【参考方案1】:

看看 Dapper 的 Multi-Mapping 功能。

Dapper 允许您将单行映射到多个对象。这是一个 如果您想避免无关查询和急切加载,则为关键功能 协会。

例子:

var sql = 
@"select * from #Posts p 
left join #Users u on u.Id = p.OwnerId 
Order by p.Id";

var data = connection.Query<Post, User, Post>(sql, (post, user) =>  post.Owner = user; return post;);
var post = data.First();

post.Content.IsEqualTo("Sams Post1");
post.Id.IsEqualTo(1);
post.Owner.Name.IsEqualTo("Sam");
post.Owner.Id.IsEqualTo(99);

重要说明 Dapper 假定您的 Id 列被命名为“Id”或“id”, 如果您的主键不同,或者您想拆分宽 行在“Id”以外的点,使用可选的“splitOn”参数。

【讨论】:

我认为这不是正确的答案,因为在此示例中,所有者变量是用户对象,而不是列表。如何在对象中填写列表?与此相反,如果“用户”对象中有“帖子”列表,我们如何填写帖子列表? 我找到了正确答案。 ***.com/a/17748734/793880【参考方案2】:

试试这个,我想会奏效

arts = conn.Query<Article>(query).ToList();

您还需要如下更改查询。

SELECT ART.ID AS [Id], ART.NAME AS [Name],EAN.EAN AS [BarCode] 
FROM ART,EAN
WHERE ART.ID = EAN.ID_ART;

【讨论】:

这和我做的一样,但问题是如何填写 List BarCode 因为查询... EAN.EAN AS BARCODE 不要填写它!我该怎么办? @enzop92 我认为您在BarCode 中获得了空值。 @enzop92 你也可以arts = conn.Query&lt;Article,Ean,Ean&gt;(query,(articles, eans) =&gt; articles.Article = articles; return eans; splitOn: "Code"); ).ToList();【参考方案3】:

另一种解决方案,其好处是只使用一个请求,只需两行代码,并且可以链接连接(以三个表为例):

为每个域对象覆盖 Equals 和 GetHashCode(这可以通过继承自动完成) 添加两个扩展以影响其父行的子行

请求:

var data = connection.Query<Table1, Table2, Table3, Table3>(
        @"  SELECT * FROM Table1
        LEFT JOIN Table2 ON Table1.Id = Table1Id
        LEFT JOIN Table3 ON Table2.Id = Table2Id
        WHERE Table1.Id IN @Ids",
    (t1, t2, t3) =>  t2.Table1 = t1; t3.Table2 = t2; return t3; ,
    param: new  Ids = new int[]  1, 2, 3 );

var read = data.GroupBy(t => t.Table2).DoItForEachGroup(gr => gr.Key.Table3s.AddRange(gr)).Select(gr => gr.Key).
    GroupBy(t => t.Table1).DoItForEachGroup(gr => gr.Key.Table2s.AddRange(gr)).Select(gr => gr.Key);

领域对象:

public class Table1

    public Table1()
    
        Table2s = new List<Table2>();
    

    public Guid Id  get; set; 
    public IList<Table2> Table2s  get; private set; 

    public override bool Equals(object obj)
    
        if (obj as Table1 == null) throw new ArgumentException("obj is null or isn't a Table1", "obj");
        return this.Id == ((Table1)obj).Id;
    

    public override int GetHashCode()
    
        return this.Id.GetHashCode();
    


public class Table2

    public Table2()
    
        Table3s = new List<Table3>();
    

    public Guid Id  get; set; 
    public Guid Table1Id
    
        get
        
            if (Table1 == null)
                return default(Guid);
            return Table1.Id;
        
    
    public IList<Table3> Table3s  get; private set; 
    public Table1 Table1  get; set; 

    public override bool Equals(object obj)
    
        if (obj as Table2 == null) throw new ArgumentException("obj is null or isn't a Table2", "obj");
        return this.Id == ((Table2)obj).Id;
    

    public override int GetHashCode()
    
        return this.Id.GetHashCode();
    


public class Table3

    public Table3()
    

    

    public Guid Id  get; set; 

    public Guid Table2Id
    
        get
        
            if (Table2 == null)
                return default(Guid);
            return Table2.Id;
        
    
    public Table2 Table2  get; set; 

    public override bool Equals(object obj)
    
        if (obj as Table3 == null) throw new ArgumentException("obj is null or isn't a Table3", "obj");
        return this.Id == ((Table3)obj).Id;
    

    public override int GetHashCode()
    
        return this.Id.GetHashCode();
    

扩展:

public static class CollectionExtensions

    public static void AddRange<T>(this IList<T> that, IEnumerable<T> collection)
    
        if (that == null)
            throw new ArgumentNullException("that", "that is null.");
        if (collection == null)
            throw new ArgumentNullException("collection", "collection is null.");

        if (that is List<T>)
        
            ((List<T>)that).AddRange(collection);
            return;
        

        foreach (T item in collection)
            that.Add(item);
    

    public static IEnumerable<IGrouping<TKey, TElem>> DoItForEachGroup<TKey, TElem>(this IEnumerable<IGrouping<TKey, TElem>> group, Action<IGrouping<TKey, TElem>> action)
    
        if (group == null)
            throw new ArgumentNullException("group", "group is null.");
        if (action == null)
            throw new ArgumentNullException("action", "action is null.");

        group.ToList().ForEach(gr => action(gr));
        return group;
    

【讨论】:

以上是关于使用 dapper c# 填充列表对象的主要内容,如果未能解决你的问题,请参考以下文章

如何使用对象 MVC 5 C# 的 Javascript 列表填充剃刀 DropDownListFor

使用 Dapper 映射嵌套对象列表(3 级嵌套对象)

使用 Dapper 映射嵌套对象列表

C# Dapper基本三层架构使用 (架构关系)

dapper 多对多查询对象和对象列表

dapper 多对多查询对象和对象列表