Dapper学习 - 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; }
}

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

posted @ 2016-11-10 13:14  Sniper_ZL  阅读(16872)  评论(3编辑  收藏  举报