首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

尝试让查询更简单

编程知识
2024年09月28日 14:49

为什么要写

为什么要写,大概就是沉没成本吧

只是从Source Generators出来开始,就打算以其研究是否能做 aop (现在已经有内置功能了),本来当年就想尝试能否在 orm 做一些尝试,可惜种种原因,自己都忘了这个打算了

直到今年7月份,才又想起了这个打算,现在精力不行了,本来研究一下原理和功能限制也算完了,

可是都写了蛮久了,不写完整点,感觉有点浪费,又花了不少时间才把 类似 DapperAOT 功能做的差不多

写完了又觉得光复制复制功能 没意思, 所以又把以前为了在公司内少写一些比较重复性代码做的 查询定制功能 在 sv.db 基础上搞一把, 反正成本已经花了那么多了

虽然这也不算多大创新, 类似想法老早就不少人搞了,比如最夸张的 graphql 这一套甚至让大家的基础设施都得搭一套,

不过越搞越多,都到国庆了,目前还只能算主体完成了,细节还有很多没搞

很多转换 解析都是手写的,不是因为写的nb,只是引入其他库兼容可能有点麻烦,场景不多,递归遍历就够了

nuget 什么的也没空搞了,bug 估计不少,等后面再完整点再搞,反正都是自娱自乐

真是年纪大了,做什么都越来越慢了

sv.db 能做什么

1. db映射到实体

DapperAOT 一样,使用 Source Generators 在构建期间生成必要的代码,以帮助您更轻松地使用 sql。

理论上,您还可以进行 Native AOT 部署

其实没什么,举个栗子吧

public async Task<object> OldWay()
{
    var a = factory.GetConnection(StaticInfo.Demo);
    using var dd = await a.ExecuteReaderAsync("""
SELECT count(1)
FROM Weather;
SELECT *
FROM Weather;
""");
    var t = await dd.QueryFirstOrDefaultAsync<int>();
    var r = await dd.QueryAsync<string>().ToListAsync();
    return new { TotalCount = t, Rows = r };
}

2. 让查询编码简单,并支持更复杂的条件

通过定义一些简单的查询规则,我们可以将 查询转换为 db / api / es 查询语句 ....

目前只搞了 db 转换,并且还没空完整适配测试, es 、mongodb 什么等后面有空把

不过理论上,我们可以这样做:

http query string / body  |------>  select statement    |------>  db (sqlite / mysql/ sqlserver / PostgreSQL)
Expression code           |------>                      |------>  es
                                                        |------>  mongodb
                                                        |------>  more .....

中间 select statement 这一层已经定义好了,前面的转换也有了, 后面的理论加上适配,什么都可以做,

2.1 举个 api 的栗子

Code exmples:

首先定义一个 实体配置, 列明哪些字段可以查,可以排序,可以筛选

[Db("Demo")]
[Table(nameof(Weather))]
public class Weather
{ 
 [Select, Where, OrderBy]
 public string Name { get; set; }

 [Select(Field = "Value as v"), Where, OrderBy]
 public string V { get; set; }

 [Select(NotAllow = true)]
 public string Test { get; set; }
}

然后定义 查询接口

[HttpGet] 
public async Task<object> Selects() //  你可以自己做一些字段,授权检查 [FromQuery, Required] string name) 
{
    return await this.QueryByParamsAsync<Weather>();
}

接着你就可以让用户自己拼写各种条件,让她们自己满足自己的场景,这样自己可以多摸一会鱼了

curl --location 'http://localhost:5259/weather?where=not (name like '%e%')&TotalCount=true'

Response

{
    "totalCount": 1,
    "rows": [
        {
            "name": "H",
            "v": "mery!"
        }
    ]
}
2.2 同样可以让查询代码更简单
Code exmples:

其实很多 orm 都提供用Expression 达到类似或更复杂效果的

这里考虑工作量,restful api 和其他数据查询实现 支持度不一,目前只做基础filter 支持, join 什么都不搞了,就算搞了多半又会被骂,直接写sql 不更好吗?

比如下面 query Weather which name no Contains 'e'

public async Task<object> DoSelects()
{
    return await factory.ExecuteQueryAsync(From.Of<Weather>().Where(i => !i.Name.Like("e")).WithTotalCount());
}

这里就非常简单介绍一下,复杂的,怎么实现的不写,累了,写不动了,要有感兴趣的 可以在 gayhub 看源码 https://github.com/fs7744/sv.db

下面再列举一下过滤操作符支持情况

Query in api

Both has func support use query string or body to query

body or query string will map to Dictionary<string, string> to handle

operater

such filter operater just make api more restful (Where=urlencode(complex condition) will be more better)

  • {{nl}} is null
    • query string ?name={{nl}}
    • body {"name":"{{nl}}"}
  • {{eq}} Equal =
    • query string ?name=xxx
    • body {"name":"xxx"}
  • {{lt}} LessThan or Equal <=
    • query string ?age={{lt}}30
    • body {"age":"{{lt}}30"}
  • {{le}} LessThan <
    • query string ?age={{le}}30
    • body {"age":"{{le}}30"}
  • {{gt}} GreaterThan or Equal >=
    • query string ?age={{gt}}30
    • body {"age":"{{gt}}30"}
  • {{gr}} GreaterThan >
    • query string ?age={{gr}}30
    • body {"age":"{{gr}}30"}
  • {{nq}} Not Equal !=
    • query string ?age={{nq}}30
    • body {"age":"{{nq}}30"}
  • {{lk}} Prefix Like 'e%'
    • query string ?name={{lk}}e
    • body {"name":"{{lk}}e"}
  • {{rk}} Suffix Like '%e'
    • query string ?name={{rk}}e
    • body {"name":"{{rk}}e"}
  • {{kk}} Like '%e%'
    • query string ?name={{kk}}e
    • body {"name":"{{kk}}e"}
  • {{in}} in array (bool/number/string)
    • query string ?name={{in}}[true,false]
    • body {"name":"{{in}}[\"s\",\"sky\"]"}
  • {{no}} not
    • query string ?age={{no}}{{lt}}30
    • body {"age":"{{no}}{{lt}}30"}

Func Fields:

  • Fields return some Fields , no Fields or Fields=* is return all
    • query string ?Fields=name,age
    • body {"Fields":"name,age"}
  • TotalCount return total count
    • query string ?TotalCount=true
    • body {"TotalCount":"true"}
  • NoRows no return rows
    • query string ?NoRows=true
    • body {"NoRows":"true"}
  • Offset Offset Rows index
    • query string ?Offset=10
    • body {"Offset":10}
  • Rows Take Rows count, default is 10
    • query string ?Rows=100
    • body {"Rows":100}
  • OrderBy sort result
    • query string ?OrderBy=name:asc,age:desc
    • body {"OrderBy":"name:asc,age:desc"}
  • Where complex condition filter
    • query string ?Where=urlencode( not(name like 'H%') or name like '%v%' )
    • body {"Where":"not(name like 'H%') or name like '%v%'"}
    • operaters
      • bool
        • example true or false
      • number
        • example 12323 or 1.324 or -44.4
      • string
        • example 'sdsdfa' or 'sds\'dfa' or "dsdsdsd" or "fs\"dsf"
      • = null is null
        • example name = null
      • = Equal
        • example name = 'sky'
      • <= LessThan or Equal
        • example age <= 30
      • < LessThan
        • example age < 30
      • >= GreaterThan or Equal
        • example age >= 30
      • > GreaterThan
        • example age > 30
      • != Not Equal
        • example age != 30
      • like 'e%' Prefix Like
        • example name like 'xx%'
      • like '%e' Suffix Like
        • example name like '%xx'
      • like '%e%' Like
        • example name like '%xx%'
      • in () in array (bool/number/string)
        • example in (1,2,3) or in ('sdsdfa','sdfa') or in (true,false)
      • not
        • example not( age <= 30 )
      • and
        • example age <= 30 and age > 60
      • or
        • example age <= 30 or age > 60
      • ()
        • example (age <= 30 or age > 60) and name = 'killer'
From:https://www.cnblogs.com/fs7744/p/18437966
本文地址: http://www.shuzixingkong.net/article/2379
0评论
提交 加载更多评论
其他文章 使用MessagePipe实现进程间通信
1、MessagePipe介绍 可以用于.NET和Unity上面的高性能的内存/分布式消息传递管道。适用于发布/订阅模式、CQRS的中介模式、Prism中的EventAggregator、IPC(进程间通信)-RPC等。 支持: 依赖注入 过滤器管道 更好的事件 同步/异步 带键值的/无键值的 单例
使用MessagePipe实现进程间通信 使用MessagePipe实现进程间通信 使用MessagePipe实现进程间通信
IntelliJ IDEA插入时间文本
IntelliJ IDEA插入时间文本 需求: 在使用IDEA编辑一些文本时,需要插入指定格式的当前时间文本,首先想到的是找找有没有相关的IDEA插件,看到确实有别的猿做过相关的插件,但当时找到的文章是需要下载博主提供的离线插件jar包,而且时间格式是否能灵活自定义还未知,且当时刚好灵光一现,有了别
IntelliJ IDEA插入时间文本 IntelliJ IDEA插入时间文本 IntelliJ IDEA插入时间文本
从设计到代码:探索高效的前端开发工具与实践
最近我对前端开发产生了浓厚的兴趣,尤其想要尝试一些新的界面设计。然而,我遇到了一个棘手的问题:在完成UI设计后,如何将其高效地转化为HTML或其他前端框架的代码。尽管最后我还是花了不少时间逐行敲代码,但我希望分享我的过程,以便为其他有相似需求的人提供参考。也许有人会从中获益,这样就能避免再次浪费时间
从设计到代码:探索高效的前端开发工具与实践 从设计到代码:探索高效的前端开发工具与实践 从设计到代码:探索高效的前端开发工具与实践
.NEET跨平台绘图基础库--SkiaSharp
SkiaSharp 是一个跨平台的 2D 图形 API,用于 .NET 平台,基于 Google 的 Skia 图形库。它提供了全面的 2D API,可以在移动、服务器和桌面模型上渲染图像。SkiaSharp 可以在多个 .NET 平台上使用,包括 ASP.NET Core、WPF、Winform、
[使用目前最新版]HybridCLR6.9.0+YooAsset2.2.4实现纯C# Unity热更新方案 (一)
1.前言 什么是热更新 游戏或者软件更新时,无需重新下载客户端进行安装,而是在应用程序启动的情况下,在内部进行资源或者代码更新 Unity目前常用热更新解决方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用资源管理解决方案 AssetBundles,Addressable,
[使用目前最新版]HybridCLR6.9.0+YooAsset2.2.4实现纯C# Unity热更新方案 (一) [使用目前最新版]HybridCLR6.9.0+YooAsset2.2.4实现纯C# Unity热更新方案 (一) [使用目前最新版]HybridCLR6.9.0+YooAsset2.2.4实现纯C# Unity热更新方案 (一)
【漏洞分析】20240507-SATURN:当闪电贷遇上有缺陷的通缩机制
背景信息 2024 年 5 月 6 日,SATURN 代币遭受价格操控攻击,损失 15 BNB。攻击发生的原因是由于 SATURN 代币的代币通缩机制设计不合理,使得攻击者可以通过燃烧池子中的 SATURN 代币来操控价格完成获利。 项目社媒:https://x.com/Saturn_POM 社媒告
【漏洞分析】20240507-SATURN:当闪电贷遇上有缺陷的通缩机制 【漏洞分析】20240507-SATURN:当闪电贷遇上有缺陷的通缩机制 【漏洞分析】20240507-SATURN:当闪电贷遇上有缺陷的通缩机制
volatile关键字最全原理剖析
介绍 volatile是轻量级的同步机制,volatile可以用来解决可见性和有序性问题,但不保证原子性。 volatile的作用: 保证了不同线程对共享变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。 禁止进行指令重排序。 底层原理 内存屏障 volatil
volatile关键字最全原理剖析 volatile关键字最全原理剖析 volatile关键字最全原理剖析
为什么用 AWS CLI?因为我懒得点鼠标!
在这篇博客中,我们一起深入探索 AWS CLI 的世界,从零开始,逐步构建在云端的家园。将介绍 AWS CLI 的基本功能和使用场景,如何创建 IAM 用户、VPC、子网、安全组、EC2 实例等,甚至还会搭建一个应用负载均衡器(ALB)。无论你是初学者还是有一定基础的用户,都能通过本指南掌握 AWS
为什么用 AWS CLI?因为我懒得点鼠标! 为什么用 AWS CLI?因为我懒得点鼠标! 为什么用 AWS CLI?因为我懒得点鼠标!