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 关联实体过滤和排序 问题 你有一实体的实例,你想加载应用了过滤和排序的相关 ...
随机推荐
- java:static详解
1.static修饰的变量习惯称为静态变量,static修饰的方法称为静态方法,static修饰的代码块叫做静态代码块. 1)static变量 static变量也称作静态变量,静态变量和非静态变量的区 ...
- 用rpm命令安装定时器crontab
crontab -l command not found 准备以下安装包: ls -l总用量 1004-rw-r--r-- 1 root root 76296 10月 9 16:01 croni ...
- Django的开始
一 浏览器相关知识 http:只有依赖一回,属于短链接,不会报错客户端的信息. 浏览器相当于一个客户端,客户端的链接 服务端:socket服务端,起服务监听客户端的请求. import socket ...
- docker 批量操作容器
docker stop $(sudo docker ps -q)
- 2019.01.22 hdu5195 DZY Loves Topological Sorting(贪心+线段树)
传送门 题意简述:给出一张DAGDAGDAG,要求删去不超过kkk条边问最后拓扑序的最大字典序是多少. 思路:贪心帮当前不超过删边上限且权值最大的点删边,用线段树维护一下每个点的入度来支持查询即可. ...
- DevOps:软件架构师行动指南(文摘)
第一部分 背景 第1章 DevOps是什么 第二部分 部署流水线 第三部分 横切关注点 第四部分 案例研究 第五部分 走向未来
- kvm虚拟化平台搭建
一.虚拟化 虚拟化是指计算机元件在虚拟的基础上而不是真实的基础上运行.虚拟化技术可以扩大硬件的容量,简化软件的重新配置过程.CPU的虚拟化技术可以单CPU模 拟多CPU并行,允许一个平台同时运行多个操 ...
- centos7.2下安装python3.6.2
centos7.2默认已经安装了python2.7.5,因此要安装python3.6的话,得从python官网上下载相应版本的安装包 查看python2.7 1.下载:wget https://www ...
- 好文推荐系列--------(1)bower---管理你的客户端依赖
好文原文地址:http://segmentfault.com/a/1190000000349555 编者注:我们发现了比较有趣的系列文章<30天学习30种新技术>,准备翻译,一天一篇更新, ...
- Codeforces Round#412 Div.2
A. Is it rated? 题面 Is it rated? Here it is. The Ultimate Question of Competitive Programming, Codefo ...