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

一、一对一映射

sql = "select Sex, Id, Name, CreateDate, No from tch_teacher limit 3;";
var list = conn.Query<Tch_Teacher>(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; }
}

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

时间: 2024-10-23 06:18:13

Dapper学习 - Dapper的基本用法(一)的相关文章

Dapper学习(三)之其他用法

这里说的其他用法,是指 Async,Buffered,Transaction,Stored Procedure. 1. 首先 dapper支持异步 ExecuteAsync, QueryAsync, QueryFirstAsync, QueryFirstOrDefaultAsync, QuerySingleAsync, QuerySingleOrDefaultAsync, QueryMultipleAsync ExecuteAsync 用法示例: string sql = "INSERT INT

Dapper学习 - Dapper.Rainbow(三) - Read

前面已经介绍了新增/修改/删除了, 接下来介绍一下Rainbow的Read方法. 一.Read -- Rainbow原生 1. 先看测试代码 var conStr = ConfigurationManager.ConnectionStrings["Cons"].ToString(); using (var conn = new MySqlConnection(conStr)) { var db = Rainbow.Init(conn, 2000); //Rainbow提供方法 var

Dapper学习 - Dapper.Rainbow(二) - Update

上一篇介绍了Rainbow的Create方法, 这里就来介绍一下Update方法吧, 毕竟新增和修改是双胞兄弟嘛. 一.Update 测试代码: var conStr = ConfigurationManager.ConnectionStrings["Cons"].ToString(); using (var conn = new MySqlConnection(conStr)) { var db = Rainbow.Init(conn, 2000); try { db.BeginTr

学习AngularJs:Directive指令用法(完整版)

这篇文章主要学习AngularJs:Directive指令用法,内容很全面,感兴趣的小伙伴们可以参考一下 本教程使用AngularJs版本:1.5.3 AngularJs GitHub: https://github.com/angular/angular.js/ AngularJs下载地址:https://angularjs.org/ 摘要:Directive(指令)笔者认为是AngularJ非常强大而有有用的功能之一.它就相当于为我们写了公共的自定义DOM元素或LASS属性或ATTR属性,并

Linux学习闲谈(三) ——SVN用法及切版本与合版本

Linux学习闲谈(三) --SVN用法及切版本与合版本 (转载请附上本文链接--linhxx) SVN(Subversion)在工程中运用广泛,多人合作项目.项目版本控制等方面,SVN都是不可或缺的.虽然最近很多项目也在使用Git,但SVN仍是现在流行的版本控制系统.SVN与Git相比,最大的一个优势是存在全局版本号. 一.概述 SVN分为客户端和服务端,即需要在一台大家都能访问到的服务器上安装SVN的服务端,然后各自的电脑里安装SVN的客户端.安装的过程这里不讲,有很多博客如http://w

Dapper学习笔记(一)

https://github.com/StackExchange/dapper-dot-net Dapper是对IDbConnection的扩展,需要使用Dapper提供的扩展只需要把SqlMapper这个文件放到自己的项目中即可.这样项目中的IDbConnection就可以直接使用Dapper中的扩展方法,这是怎么实现的呢?百度才知道这个是C#提供的扩展方法. 扩展方法如何使用呢?直接看代码. 对Object写一个自定义的ToString()方法,输出"自定义Object的ToString()

Dapper学习笔记(2)-链接引用

在研究Dapper源码时发现Dapper NET45类库中的SqlMapper.cs文件前面有个蓝色的箭头图标,发现在Dapper NET45文件夹下根本不存在SqlMapper.cs文件,其文件属性中的完整路径指向了Dapper NET40文件夹中的SqlMapper.cs文件,如下图: 后发现其为一个链接引用,代码文件只有一份,但是可以被多个项目所包含.在项目里面添加一个已存在的文件时选择“添加为链接”即可,具体操作如下:

Dapper 学习笔记

一.基础 1.Dapper代码就一个SqlMapper.cs文件, 前人测试Dapper速度较快 的Orm,读取速度接近IDataReader,超过DataTable. 2.a.下载地址 https://github.com/StackExchange/dapper-dot-net ,包含在线示例 (test project).b.net 下可以通过 Nuget下载. 3.实体类用NHibernateMappingGenerator生成. 二.示例代码 1.sql脚本 USE [FactoryD

Dapper学习笔记(4)-事务

Dapper中对事务的处理也非常简单,如下代码所示: 1 private void DapperTransaction() 2 { 3 using (IDbConnection con = OpenConnection()) 4 { 5 IDbTransaction tran = con.BeginTransaction(); 6 try 7 { 8 string query = "update T_Role set RoleName='开发主管' where RoleId=4";//