Dapper实现一对多对象关系聚合导航属性
领域对象:Game(游戏), Room(游戏群),两者一对多的关系,SQL语句中会用到JOIN
- public class Game : AggregateRoot
- {
- public string Tag { get; set; }
- public string Title { get; set; }
- public string Description { get; set; }
- public IEnumerable<Room> Rooms { get; set; }
- public Game()
- {
- this.Rooms = new HashSet<Room>();
- }
- public void SetRooms(IEnumerable<Room> rooms)
- {
- this.Rooms = this.Rooms.Concat(rooms);
- }
- }
- public class Room : Entity
- {
- public int GameId{ get; set; }
- public intstring Name { get; set; }
- public int Limit { get; set; }
- public string Owner { get; set; }
- }
通常用Dapper的Query<TFirst,TSecond,TReturn>() 或 QueryAsync<TFirst,TSecond,TReturn>() 是可以实现,但是去除重复记录比较麻烦。
所以我们扩展两个Query/QueryAsync方法:
- /// <summary>
- /// 查询带聚合导航属性的对象集合
- /// </summary>
- /// <typeparam name="TFirst">主体对象类型</typeparam>
- /// <typeparam name="TSecond">聚合导航对象类型</typeparam>
- /// <param name="setting">设置聚合导航属性的方法</param>
- public static IEnumerable<TFirst> Query<TFirst, TSecond>(this IDbConnection cnn, string sql, Action<TFirst, TSecond> setting, object param = null, string splitOn = "Id")
- where TFirst : class, IEntity<int>
- where TSecond : class, IEntity<int>
- {
- TFirst lookup = null;
- var hashes = new HashSet<TFirst>();
- cnn.Query<TFirst, TSecond, TFirst>(sql, (first, second) =>
- {
- //第一条记录,或者新的主体记录,否则lookup还是上一条记录
- if (lookup == null || lookup.Id != first.Id)
- lookup = first;
- if (second != null && second.Id > && setting != null)
- setting(lookup, second);
- if (!hashes.Any(m => m.Id == lookup.Id))
- hashes.Add(lookup);
- return null;
- }, param: param, splitOn: splitOn);
- return hashes;
- }
- /// <summary>
- /// 异步查询带聚合导航属性的对象集合
- /// </summary>
- /// <typeparam name="TFirst">主体对象类型</typeparam>
- /// <typeparam name="TSecond">聚合导航对象类型</typeparam>
- /// <param name="setting">设置聚合导航属性的方法</param>
- public static async Task<IEnumerable<TFirst>> QueryAsync<TFirst, TSecond>(this IDbConnection cnn, string sql, Action<TFirst, TSecond> setting, object param = null, string splitOn = "Id")
- where TFirst : class, IEntity<int>
- where TSecond : class, IEntity<int>
- {
- TFirst lookup = null;
- var hashes = new HashSet<TFirst>();
- await cnn.QueryAsync<TFirst, TSecond, TFirst>(sql, (first, second) =>
- {
- //第一条记录,或者新的主体记录,否则lookup还是上一条记录
- if (lookup == null || lookup.Id != first.Id)
- lookup = first;
- if (second != null && second.Id > && setting != null)
- setting(lookup, second);
- if (!hashes.Any(m => m.Id == lookup.Id))
- hashes.Add(lookup);
- return null;
- }, param: param, splitOn: splitOn);
- return hashes;
- }
调用示例:
- return await _db.QueryAsync<Game, Room>("SELECT * FROM game g LEFT JOIN room r ON r.gameid = g.id", (game, room) =>
- {
- game.SetRooms(new HashSet<Room> { room });
- }, splitOn: "Id");
Dapper实现一对多对象关系聚合导航属性的更多相关文章
- 关系与导航属性(摘自微软MSDN)
关系与导航属性 本主题概述实体框架如何管理实体间的关系.还对如何映射和操作关系提供了一些指南. 关系.导航属性和外键 在关系数据库中,表之间的关系(也称为关联)是通过外键定义的.外键 (FK) 是用于 ...
- Hibernate单向一对多对象关系模型映射
1 hibernate 的对象关系映射 Orm: 类-----表 属性------字段 对象------记录 表:在数据库中存在主外键的关系,反向工厂类是由表生成,在由表生成类的时候,类和类之间存在者 ...
- Hibernate双向一对多对象关系模型映射
双向one-to-many 描述部门和岗位:一个部门有多个岗位 将单向的one-to-many 和many-to-one合并. 4.1双向的one-to-many数据库模型 create table ...
- FreeSql (十八)导航属性
导航属性是 FreeSql 的特色功能之一,可通过约定配置.或自定义配置对象间的关系. 导航属性有 OneToMany, ManyToOne, ManyToMany, OneToOne, Parent ...
- MVC3+EF4.1学习系列(五)----- EF查找导航属性的几种方式
文章索引和简介 通过上一篇的学习 我们把demo的各种关系终于搭建里起来 以及处理好了如何映射到数据库等问题 但是 只是搭建好了关系 问题还远没有解决 这篇就来写如何查找导航属性 和查找导航属性的几种 ...
- FreeSql 导航属性的联级保存功能
写在前面 FreeSql 一个款 .net 平台下支持 .net framework 4.5+..net core 2.1+ 的开源 ORM.单元测试超过3100+,正在不断吸引新的开发者,生命不息开 ...
- MyBatis加强(1)~myBatis对象关系映射(多对一关系、一对多关系)、延迟/懒加载
一.myBatis对象关系映射(多对一关系.一对多关系) 1.多对一关系: ---例子:多个员工同属于一个部门. (1)myBatis发送 额外SQL: ■ 案例:员工表通过 dept_id 关联 部 ...
- [LINQ2Dapper]最完整Dapper To Linq框架(八)---导航属性
目录 [LINQ2Dapper]最完整Dapper To Linq框架(一)---基础查询 [LINQ2Dapper]最完整Dapper To Linq框架(二)---动态化查询 [LINQ2Dapp ...
- 《Entity Framework 6 Recipes》中文翻译系列 (27) ------ 第五章 加载实体和导航属性之关联实体过滤、排序、执行聚合操作
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-9 关联实体过滤和排序 问题 你有一实体的实例,你想加载应用了过滤和排序的相关 ...
随机推荐
- python之面向对象篇6
一.继承与派生 什么是继承 继承一种新建类的方式,新建的类称为子类或者派生类,被继承的类称为父类或基类或超类 子类会遗传父类的一系列属性 python支持多继承 注意: 在python3中,如果没有显 ...
- linux_配置三台虚拟机免密登录
在node01上面直接生成公钥和私钥 ssh-keygen --> 四下回车 ll -a 进行查看,发现出现.ssh文件即已经生成 将此node01的公钥拷贝到第二台机器上 ssh-copy-i ...
- ubuntu下安装/卸载vmware虚拟机
1.下载vmware(官网下载试用版,试用版输入序列号后即为专业版,序列号网上搜,很多) 2.下载后安装(命令行) 1)cd进你下载的位置 1.1)下载的文件名字为:VMware-Workstatio ...
- 树状数组(hdu-4325,hdu-1166,pat-1057)
1.hdu-4325 题意:插花,要么给出插花的范围,要么查询某个点的花的个数. 思路:通过更新,每次更新区间S到T的数值,表插入花(这一点一开始没想到), 要么查询某个点的花的数目. (与以往单纯的 ...
- urllib — URL handling modules
urllib is a package that collects several modules for working with URLs: •urllib.request for opening ...
- IntelliJ IDEA 2017版 spring-boot2.0.4的集成JSP
一.必须依赖四个包,其中三个是springboot自带包,可以不写版本号,有一个不在springboot中,需要设置版本号 <!--引入Spring Boot内嵌的Tomcat对Jsp的解析包- ...
- VMware Workstation “以独占方式锁定此配置文件失败。可能其它正在运行VMware进程在使用此配置文件”
VMware Workstation客户机异常关闭之后,再启动时提示“以独占方式锁定此配置文件失败...”. 解决方法: 进入客户机的安装目录(注意,非VMware的安装目录),删除所有后缀为lck的 ...
- 25个Linux相关的网站
下面是25个最具有影响力,也是最重要的Linux网站,这些网站提供了Linux的分发包,软件,文件,新闻,以及其它所有的关于Linux的东西.关于Linux的分发包历史,可以看看本站的这篇文章< ...
- day22(过滤器Filter)
过滤器 生命周期:初始化 -----过滤-------销毁 作用:过滤url ,特定字符 创建方式:实现一个接口继承Filter package com.baidu.filter; import ja ...
- [转]Android中Intent传递对象的两种方法(Serializable,Parcelable)
http://blog.csdn.net/xyz_lmn/article/details/5908355 今天要给大家讲一下Android中Intent中如何传递对象,就我目前所知道的有两种方法,一种 ...