Dapper实现一对多对象关系聚合导航属性

时间:2022-08-29 22:22:21

领域对象: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实现一对多对象关系聚合导航属性的更多相关文章

  1. 关系与导航属性&lpar;摘自微软MSDN&rpar;

    关系与导航属性 本主题概述实体框架如何管理实体间的关系.还对如何映射和操作关系提供了一些指南. 关系.导航属性和外键 在关系数据库中,表之间的关系(也称为关联)是通过外键定义的.外键 (FK) 是用于 ...

  2. Hibernate单向一对多对象关系模型映射

    1 hibernate 的对象关系映射 Orm: 类-----表 属性------字段 对象------记录 表:在数据库中存在主外键的关系,反向工厂类是由表生成,在由表生成类的时候,类和类之间存在者 ...

  3. Hibernate双向一对多对象关系模型映射

    双向one-to-many 描述部门和岗位:一个部门有多个岗位 将单向的one-to-many 和many-to-one合并. 4.1双向的one-to-many数据库模型 create table ...

  4. FreeSql (十八)导航属性

    导航属性是 FreeSql 的特色功能之一,可通过约定配置.或自定义配置对象间的关系. 导航属性有 OneToMany, ManyToOne, ManyToMany, OneToOne, Parent ...

  5. MVC3&plus;EF4&period;1学习系列&lpar;五&rpar;----- EF查找导航属性的几种方式

    文章索引和简介 通过上一篇的学习 我们把demo的各种关系终于搭建里起来 以及处理好了如何映射到数据库等问题 但是 只是搭建好了关系 问题还远没有解决 这篇就来写如何查找导航属性 和查找导航属性的几种 ...

  6. FreeSql 导航属性的联级保存功能

    写在前面 FreeSql 一个款 .net 平台下支持 .net framework 4.5+..net core 2.1+ 的开源 ORM.单元测试超过3100+,正在不断吸引新的开发者,生命不息开 ...

  7. MyBatis加强(1)~myBatis对象关系映射(多对一关系、一对多关系)、延迟&sol;懒加载

    一.myBatis对象关系映射(多对一关系.一对多关系) 1.多对一关系: ---例子:多个员工同属于一个部门. (1)myBatis发送 额外SQL: ■ 案例:员工表通过 dept_id 关联 部 ...

  8. &lbrack;LINQ2Dapper&rsqb;最完整Dapper To Linq框架&lpar;八&rpar;---导航属性

    目录 [LINQ2Dapper]最完整Dapper To Linq框架(一)---基础查询 [LINQ2Dapper]最完整Dapper To Linq框架(二)---动态化查询 [LINQ2Dapp ...

  9. 《Entity Framework 6 Recipes》中文翻译系列 &lpar;27&rpar; ------ 第五章 加载实体和导航属性之关联实体过滤、排序、执行聚合操作

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-9  关联实体过滤和排序 问题 你有一实体的实例,你想加载应用了过滤和排序的相关 ...

随机推荐

  1. mysql用户名密码忘记了解决方法

    今天想用一下实验室服务器的mysql,发现不记得用户名密码了. 解决方法如下: 1. 保证服务器处于安全的状态,如果可以请拔掉网线...(不过我跳过了这一步,额) 2. 修改/etc/my.cnf文件 ...

  2. sql移除换行回车符号 &bsol;r&bsol;n

    --移除回车符 update master_location SET street_number = REPLACE(street_number, CHAR(13), '') --移除换行符 upda ...

  3. mobile web HTML5 app曾经的踩过坑&lpar;转&rpar;

    兼容性一直是前端工程师心中永远的痛.手机浏览器,因为基本是webkit(blink)内核当道,很多公司,不用考虑IE系的浏览器,所以感觉兼容性上的问题可能会少一些. 但是手机端,虽然出了很多工具,但是 ...

  4. 获取bing每日图片

    http://global.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US 其中idx表示倒数第几张图片 ...

  5. js打印(控件)及多种方式

    非常好用的LODOP打印控件 Lodop打印控件简单使用方法 1.安装. 2.调用LodopFuncs.js文件. 3.增加OBJECT对象 <script language="jav ...

  6. JavaScript Web Application summary

    Widget/ HTML DOM (CORE) (local dom) DOM, BOM, Event(Framework, UI, Widget) function(closure) DATA (c ...

  7. Spring dbcp连接池简单配置 示例

    一.配置db.properties属性文件 #database connection config connection.username=sa connection.password=sa conn ...

  8. SecureCRT安装

    第一步:下载SecureCRT&SecureCRT激活工具 首先下载SecureCRT安装包和SecureCRT激活工具,SecureCRT&SecureCRT激活工具下载地址:链接: ...

  9. Hadoop 管理工具HUE配置-初始配置

    1 界面换成中文 默认是英文的,可以修改为中文 1.修改配置文件settings.pynano hue/desktop/core/src/desktop/settings.py LANGUAGE_CO ...

  10. PHP之高性能I&sol;O框架:Libevent(一)

    Libevent 是一个用C语言编写的.轻量级的开源高性能I/O框架,支持多种 I/O 多路复用技术: epoll. poll. dev/poll. select 和 kqueue 等:支持 I/O, ...