news 2026/5/11 3:26:48

DBShadow.net之化繁为简

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DBShadow.net之化繁为简

一、简化查询

1. 先看一下查询的例子

/* by yours.tools - online tools website : yours.tools/zh/md5.html */ /// <summary> /// 账户获取服务 /// </summary> /// <param name="table"></param> /// <param name="builder"></param> public class AccountGetService(AccountTable table, IShadowBuilder builder) { private readonly SqlSource _source = new(builder.DataSource); private readonly IParamQuery<Account, Account> _accountQuery = builder.BuildResult<Account, Account>( table.ToQuery() .And(account => account.Id.Equal()) .ToSelect() .SelectSelfColumns() ); /// <summary> /// 获取账户 /// </summary> /// <param name="param"></param> /// <param name="token"></param> /// <returns></returns> public Task<Account?> GetAsync(Account param, CancellationToken token = default) => _accountQuery.GetFirstAsync(_source, param, token); }

2. 调用方式如下

/* by yours.tools - online tools website : yours.tools/zh/md5.html */ var account = await accountGetService.GetAsync(new Account { Id = 1L });

3. 这个例子我们可以简化一下

  • 参数直接使用Id(类型由Account简化为long)
  • 很大一部分数据库操作都只有一个参数(GetById、GetByName等)
  • 为此定义一个含单个属性类有点浪费
  • 按上面的例子使用实体类作为参数也感觉怪怪的
  • DBShadow.net支持这种简化操作
  • 单个参数无需封装,直接使用参数类型即可
public class AccountGetService(AccountTable table, IShadowBuilder builder) { private readonly SqlSource _source = new(builder.DataSource); private readonly IParamQuery<long, Account> _accountQuery = builder.BuildResult<long, Account>( table.ToQuery() .And(account => account.Id.Equal()) .ToSelect() .SelectSelfColumns() ); public Task<Account?> GetAsync(long accountId, CancellationToken token = default) => _accountQuery.GetFirstAsync(_source, param, token); } var account = await accountGetService.GetAsync(1L);

4. 特别注意不要在Dapper中这样使用

  • Dapper是不支持这种简化操作
  • 以下Dapper错误示例会抛出异常
  • System.InvalidOperationException:“Must add values for the following parameters: @Id”
await using var conn = _dataSource.CreateConnection(); var sql = "SELECT \"Id\",\"Title\",\"Content\",\"Done\",\"LastTime\" FROM \"Todo\" WHERE \"Id\"=@Id"; var first = await conn.QueryFirstOrDefaultAsync<Todo>(sql, 1L);

二、 集合参数也支持简化操作

1. IN查询简化的例子

  • In的参数化名是可选和前面例子的Equal是一样的,默认字段名
  • In查询的实参支持数组、集合及字典
  • 只有In一个集合参数是支持直接传数组、集合或字典
  • 这时参数名(eg: AccountIds)就无所谓取什么名了
  • 因为不需要反射获取属性值了
/// <summary> /// 批量账户获取服务 /// </summary> /// <param name="table"></param> /// <param name="builder"></param> public class AccountBatchService(AccountTable table, IShadowBuilder builder) { private readonly SqlSource _source = new(builder.DataSource); private readonly IParamQuery<long[], Account> _accountQuery = builder.BuildResult<long[], Account>( table.ToQuery() .And(account => account.Id.In("AccountIds")) .ToSelect() .SelectSelfColumns() ); /// <summary> /// 批量获取账户 /// </summary> /// <param name="accountIds"></param> /// <param name="token"></param> /// <returns></returns> public IAsyncEnumerable<Account> GetAsync(long[] accountIds, CancellationToken token = default) => _accountQuery.QueryAsync(_source, accountIds, token); }

2. 以上调用的例子如下

[Fact] public async Task Batch() { var count = 0; var service = new AccountBatchService(table, builder); var list = service.GetAsync([1L, 2L, 3L]); await foreach (var item in list) { _output.WriteLine($"{item.Id}:{item.Amount}"); count++; } Assert.Equal(3, count); } // 1:100 // 2:200 // 3:300

三、泛型查询

1. 泛型服务类代码

  • 该服务用来按字段Id查询表Account
  • 参数TParam是泛型,这样可以直接使用DTO参数来查询,减少类型转化的开销
  • 返回值TAccount也是泛型,这样就可以直接返回视图模型或者领域模型
  • 这样的泛型服务类就非常的通用
/// <summary> /// 账户获取泛型服务 /// </summary> /// <param name="table"></param> /// <param name="builder"></param> public class AccountGetService<TParam, TAccount>(AccountTable table, IShadowBuilder builder) { private readonly SqlSource _source = new(builder.DataSource); private readonly IParamQuery<TParam, TAccount> _accountQuery = builder.BuildResult<TParam, TAccount>( table.ToQuery() .And(account => account.Id.Equal()) .ToSelect() .SelectSelfColumns() ); /// <summary> /// 获取账户 /// </summary> /// <param name="param"></param> /// <param name="token"></param> /// <returns></returns> public Task<TAccount?> GetAsync(TParam param, CancellationToken token = default) => _accountQuery.GetFirstAsync(_source, param, token); }

2. 中规中矩的调用方式

var service = new AccountGetService<Account, Account>(_table, _builder); var account = await service.GetAsync(new Account { Id = 1L }); Assert.NotNull(account);

3. 支持简单调用方式

var service = new AccountGetService<long, Account>(_table, _builder); var account = await service.GetAsync(1L); Assert.NotNull(account);

四、总结

  • DBShadow.net预编译比较智能
  • 只有1个参数时支持化繁为简,支持直接传值做为参数值
  • 这样可以节约定义只有一个属性的参数类
  • 参数和返回值类型还可以定义为泛型,可以做到更加灵活

另外源码托管地址: https://github.com/donetsoftwork/DBShadow.net ,欢迎大家直接查看源码。
gitee同步更新:https://gitee.com/donetsoftwork/DBShadow.net

如果大家喜欢请动动您发财的小手手帮忙点一下Star,谢谢!!!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/28 23:34:08

使用torch.compile与梯度累积加速模型训练

训练一个具有深度Transformer架构的语言模型是耗时的。然而&#xff0c;有些技巧可以用来加速训练。在本文中&#xff0c;你将学习到&#xff1a; 使用 torch.compile() 加速模型使用梯度累积来训练具有更大有效批次大小的模型 让我们开始吧&#xff01; 概述 本文分为两个…

作者头像 李华
网站建设 2026/5/9 20:55:17

计算机毕业设计springboot房车旅途 基于SpringBoot的房车租赁与售卖一体化平台 SpringBoot+Vue智慧房车出行服务系统

计算机毕业设计springboot房车旅途&#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。疫情之后&#xff0c;自驾露营热度飙升&#xff0c;把“家”装在车轮上成为年轻家庭的新宠。传…

作者头像 李华
网站建设 2026/4/27 6:31:55

2005-2024年上市公司管理者短视主义数据+stata代码

数据名称&#xff1a;2005-2024年管理者短视主义数据 时间&#xff1a;2005-2024年 数据量&#xff1a;53104条 范围&#xff1a;沪深A股上市公司 包含剔除金融stpt、未剔除版本 包含原始数据、处理代码&#xff08;stata&#xff09;、最终结果 指标构建&#xff1a;基于…

作者头像 李华
网站建设 2026/5/9 2:56:05

文字游戏:进化之路2.0二开完美版本源码 带后台

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 文字游戏&#xff1a;进化之路2.0二开完美版本源码 带后台 基于原版二开。原版没有后台功能&#xff0c;前端某些功能也是没有的&#xff01; 后端部分功能参考额曜崽i的版本思路&am…

作者头像 李华
网站建设 2026/4/24 4:24:10

Node.js——Node.js 中间件与控制器实现问题

问题难点 在实现复杂的业务逻辑时&#xff0c;如何正确使用中间件处理请求、如何设计高效的控制器成为关键问题。 解决方案 Egg.js提供了灵活的中间件机制和基于装饰器的控制器实现方式。 Demo代码&#xff1a; // app/middleware/auth.ts - 认证中间件 import { Context, Next…

作者头像 李华
网站建设 2026/4/26 19:10:38

uni-app—— 小程序表单页面键盘弹起布局错乱问题

问题现象 表单页面点击输入框&#xff0c;键盘弹起后&#xff1a;平台表现安卓输入框位置错位&#xff0c;光标飘到其他位置iOS键盘遮挡输入框&#xff0c;看不到输入内容问题原因 当页面同时存在以下三个因素时&#xff0c;容易出现布局错乱&#xff1a; scroll-view float布…

作者头像 李华