PixelMentor:一个开源网站 · 调用AI视觉能力分析图片 · 提供影视后期修改意见

一、简化查询

  1. 先看一下查询的例子

///
/// 账户获取服务

///

///

///

public class AccountGetService(AccountTable table, IShadowBuilder builder)

{

private readonly SqlSource _source = new(builder.DataSource);

private readonly IParamQuery _accountQuery

= builder.BuildResult(

table.ToQuery()

.And(account => account.Id.Equal())

.ToSelect()

.SelectSelfColumns()

);

///
/// 获取账户

///

///

///

///

public Task GetAsync(Account param, CancellationToken token = default)

=> _accountQuery.GetFirstAsync(_source, param, token);

}

  1. 调用方式如下

var account = await accountGetService.GetAsync(new Account { Id = 1L });

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

参数直接使用Id(类型由Account简化为long)

很大一部分数据库操作都只有一个参数(GetById、GetByName等)

为此定义一个含单个属性类有点浪费

按上面的例子使用实体类作为参数也感觉怪怪的

DBShadow.net支持这种简化操作

单个参数无需封装,直接使用参数类型即可

public class AccountGetService(AccountTable table, IShadowBuilder builder)

{

private readonly SqlSource _source = new(builder.DataSource);

private readonly IParamQuery _accountQuery

= builder.BuildResult(

table.ToQuery()

.And(account => account.Id.Equal())

.ToSelect()

.SelectSelfColumns()

);

public Task GetAsync(long accountId, CancellationToken token = default)

=> _accountQuery.GetFirstAsync(_source, param, token);

}

var account = await accountGetService.GetAsync(1L);

  1. 特别注意不要在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(sql, 1L);

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

  1. IN查询简化的例子

In的参数名是可选和前面例子的Equal是一样的,默认字段名

In查询的实参支持数组、集合及字典

只有In一个集合参数时支持直接传数组、集合或字典

这时参数名(eg: AccountIds)就无所谓取什么名了

因为不需要按参数名反射获取属性了

///
/// 批量账户获取服务

///

///

///

public class AccountBatchService(AccountTable table, IShadowBuilder builder)

{

private readonly SqlSource _source = new(builder.DataSource);

private readonly IParamQuery _accountQuery

= builder.BuildResult(

table.ToQuery()

.And(account => account.Id.In("AccountIds"))

.ToSelect()

.SelectSelfColumns()

);

///
/// 批量获取账户

///

///

///

///

public IAsyncEnumerable GetAsync(long[] accountIds, CancellationToken token = default)

=> _accountQuery.QueryAsync(_source, accountIds, token);

}

  1. 以上调用的例子如下

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也是泛型,这样就可以直接返回视图模型或者领域模型

这样的泛型服务类就非常的通用

///
/// 账户获取泛型服务

///

///

///

public class AccountGetService(AccountTable table, IShadowBuilder builder)

{

private readonly SqlSource _source = new(builder.DataSource);

private readonly IParamQuery _accountQuery

= builder.BuildResult(

table.ToQuery()

.And(account => account.Id.Equal())

.ToSelect()

.SelectSelfColumns()

);

///
/// 获取账户

///

///

///

///

public Task GetAsync(TParam param, CancellationToken token = default)

=> _accountQuery.GetFirstAsync(_source, param, token);

}

  1. 中规中矩的调用方式

var service = new AccountGetService(_table, _builder);

var account = await service.GetAsync(new Account { Id = 1L });

Assert.NotNull(account);

  1. 支持简单调用方式

var service = new AccountGetService(_table, _builder);

var account = await service.GetAsync(1L);

Assert.NotNull(account);

四、总结

DBShadow.net预编译比较智能

只有1个参数时支持化繁为简,支持直接传值做为参数值

这样可以节约定义只有一个属性的参数类

参数和返回值类型还可以定义为泛型,可以做到更加灵活由鞠抛匆

相关推荐
Bau2aoic93 小时前
Skills 编写学习
分享
EUL8FUCEU3 小时前
Maomi.Core | 一个好用的模块化和自动服务注册框架
分享
rV3u0zV4U3 小时前
存储那么贵,何不白嫖飞书云文件空间
分享
kas9P0mBj3 小时前
Jenkins 学习总结
分享
gr180eoY53 小时前
OPUS编解码器在audio DSP上的移植和应用
分享
GCRK1f25f3 小时前
.NET 新特性概览与相关文章索引
分享
VEKlWXO3U4 小时前
再次革新 .NET 的构建和发布方式(三)
分享
kort02i1s4 小时前
Langchain .. 学习 --- LCEL和Runnable
分享
Kn6V2DH5M4 小时前
Sa-Token v.. 发布 ,正式支持 Spring Boot 、新增 Jackson/Snack 插件适配
分享