• Dapper学习


    上一篇, 提到Query<Test>查询的时候, 如果Test中包含自定义class, Dapper不会给自定义class完成映射, 而是直接给null, 其实是可以实现的, 答案就在下面的基本用法介绍中

     提到用法, 首先是要实现CURD, 这里先介绍Read吧.

    先上实体:

        public enum Gender
        { 
            男 = 0,
            女
        }
    
        public class Tch_Teacher
        {
            public int Id { get; set; }
    
            public Gender Sex { get; set; }
            
            public string Name { get; set; }
    
            public bool IsDoublePosition { get; set; }
    
            public DateTime CreateDate { get; set; }
        }
        public class Tch_Contact
        {
            public int Id { get; set; }
    
            public int TId { get; set; }
    
            public string Phone { get; set; }
    
            public string QQ { get; set; }
    
            public string Weixin { get; set; }
        }
        public class TeacherInfo
        {
            public Tch_Contact Contact { get; set; }
    
            public Tch_Teacher Teacher { get; set; }
        }

    一、一对一映射

    var sql = string.Empty;
    
    sql = "select Count(1) from tch_teacher where id>@Id limit 3;";
    Console.WriteLine(conn.Query<int>(sql, new { Id = 10 }));
    Console.WriteLine(conn.Query<string>(sql, new { Id = 1 }));
    
    sql = "select Sex, Id, Name, CreateDate, No from tch_teacher limit 3;";
    var list = conn.Query<Test>(sql);
    var list1 = conn.Query<object>(sql);
    var list2 = conn.Query<dynamic>(sql); Console.WriteLine(list.ToList().FirstOrDefault().Name);

    一对一映射还是蛮简单的, 不需要解释了,  这种写法, 就是前面提到的, 如果Tch_Teacher里面有一个Tch_Contact类型的属性, 那么在映射的时候, 这个属性会直接赋值为null

    二、一对多映射

    sql = @"select a.Id, a.Sex, a.Name, a.CreateDate, a.No, b.Id, b.Phone, b.QQ, 
    b.Weixin from tch_teacher a left join tch_contact b on a.Id = b.TId order by a.Id asc limit 3;
    "; //No这个字段, 在类中并没有 var list1 = conn.Query<Test, Tch_Contact, TeacherInfo>(sql, (a, b) => { TeacherInfo tInfo = new TeacherInfo(); if (a != null) { tInfo.Teacher = a; } if (b != null) { tInfo.Contact = b; } return tInfo; }); //}, null, null, true, "Id", null, null);

    此时, 返回的 List<TeacherInfo> 中, Teacher 和 Contact 都是有值的, 而不是直接给null, 当然, TeacherInfo中, 还可以有别的字段, 比如 public int No {get;set;},

    此时的No是能获取到值的. 其中的映射原理, 这里我就不再赘述了, 能看懂Dapper中一对一映射的原理, 一对多映射也就差不多了. 

     如果将 TeacherInfo类中Contact属性修改一下, 改成 List<Tch_Contact>类型, 那么怎样得到一个按 Tch_Teacher 分组的数据呢?

    通常情况下, 会想到两种办法:

    一种是上面这种办法, 先得到全部数据, 然后通过GroupBy方法, 进行分组, 也能得到那种分组数据, 但那并不理想, 这种方法我就不贴了.

      1. 得到的数据, 并不是我们想要的那种格式数据, 虽然也是分组的数据.

      2. 有重复项. Tch_Teacher并没有得到去除重复的功能. 虽然分了组, 但是每组中的数据, Tch_Teacher仍然是重复的.

     另一种, 就是通过一个中间变量来获取, 方法如下:

    sql = @"select a.Id, a.Sex, a.Name, a.CreateDate, a.No, b.Id, b.Phone, b.QQ, b.Weixin 
        from tch_teacher a left join tch_contact b on a.Id = b.TId order by a.Id asc limit 6;"; 
    var infos = new Dictionary<int, TeacherInfo>();
    var list1 = conn.Query<Test, Tch_Contact, TeacherInfo>(sql, (a, b) =>
    {
        TeacherInfo tInfo;
        if (!infos.TryGetValue(a.Id, out tInfo))
        {
            tInfo = new TeacherInfo();
            tInfo.Contact = new List<Tch_Contact>();
            tInfo.Teacher = a;
            infos.Add(a.Id, tInfo);
        }
        if (b != null)
        {
            infos[a.Id].Contact.Add(b);
        }
        return infos[a.Id];
    });

    使用字典项, 在其中进行一个规整操作, 去除重复的 Tch_Teacher信息, 把Tch_Contact进行规整分组. 而且, 得到的结果, 就直接是想要的结果

    public class TeacherInfo
    {
        public List<Tch_Contact> Contact { get; set; }
    
        public Tch_Teacher Teacher { get; set; }
    }

     话说回来, 至于最终使用哪种方法, 要根据具体使用需求来定, 总体来说, 都能达到效果. 方法无好坏, 只是使用场景不同. 

  • 相关阅读:
    Binary Tree Inorder Traversal
    Populating Next Right Pointers in Each Node
    Minimum Depth of Binary Tree
    Majority Element
    Excel Sheet Column Number
    Reverse Bits
    Happy Number
    House Robber
    Remove Linked List Elements
    Contains Duplicate
  • 原文地址:https://www.cnblogs.com/elvinle/p/6050365.html
Copyright © 2020-2023  润新知