【设计过程】.NET ORM FreeSql WhereDynamicFilter 动态表格查询功能

前言

最近几乎每天40度,越热越不想面对电脑,还好开源项目都比较稳定没那么多待解决问题,趁着暑假带着女儿学习游泳已略有小成。游泳好处太多了,建议有孩子的都去学学,我是在岸边指导大约一周左右就学会了,目前可游200米。

FreeSql 有一个用户很迷的功能 WhereDynamicFilter 动态表格查询,本文讲解它的设计初衷,如何高效理解,从此不再迷惑。

小时候学习编程,老师经常教导我们,程序 = 数据结构 + 算法,今天就以我自身的认知讲解该功能的完整设计过程,其中包含数据结构和算法。


ORM概念

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

FreeSql 是 .Net ORM,能支持 .NetFramework4.0+、.NetCore、Xamarin、MAUI、Blazor、以及还有说不出来的运行平台,因为代码绿色无依赖,支持新平台非常简单。目前单元测试数量:8500+,Nuget下载数量:900K+。QQ群:4336577(已满)、8578575(在线)、52508226(在线)

FreeSql 使用最宽松的开源协议 MIT https://github.com/dotnetcore/FreeSql ,完全可以商用,文档齐全,甚至拿去卖钱也可以。

FreeSql 主要优势在于易用性上,基本是开箱即用,在不同数据库之间切换兼容性比较好,整体的功能特性如下:

  • 支持 CodeFirst 对比结构变化迁移;
  • 支持 DbFirst 从数据库导入实体类;
  • 支持 丰富的表达式函数,自定义解析;
  • 支持 批量添加、批量更新、BulkCopy;
  • 支持 导航属性,贪婪加载、延时加载、级联保存;
  • 支持 读写分离、分表分库,租户设计;
  • 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/神通/人大金仓/翰高/MsAccess Ado.net 实现包,以及 Odbc 的专门实现包;

8500+个单元测试作为基调,支持10多数数据库,我们提供了通用Odbc理论上支持所有数据库,目前已知有群友使用 FreeSql 操作华为高斯、mycat、tidb 等数据库。安装时只需要选择对应的数据库实现包:

dotnet add packages FreeSql.Provider.MySql


需求矛盾

虽然 ORM 有理论定义支撑,但实际开发过程中,难免遇到动态查询的需求,常见的有后台管理系统用户自定义过滤查询,如:

【设计过程】.NET ORM FreeSql WhereDynamicFilter 动态表格查询功能_第1张图片

鉴于实际与理论的矛盾,导致很多非常实用的功能类库让一些人诟病,指这是 SqlHelper,并非 ORM,在此不便理论,功过自在人心。


数据结构

数据结构的定义,决定了功能的使用深度,这块也参考了一些竟品类似的功能,实际在 .NET ORM 领域很少有完美并简单的现实,要么使用太复杂,要么不支持深层级。

类似的功能其实市面产品应用挺广泛,几乎已经形成了一套成熟的产品规则。如果不是亲身经历过类似产品,是很难定义出完美的数据结构的,作为一个公众开源项目,API 一旦确定再改是非常痛苦的决定,用户升级不兼容的情况不仅会影响 FreeSql 口碑,还会让使用者进退两难,到底要不要升级?好在 FreeSql 从 2018 年最初理念保持至今,关于前后破坏性升级几乎没有。

最终根据对 SQL 逻辑表达式的理解,加上参考 JAVA 一个知名的后台开源框架,取长补短确定了最终数据结构。

说这么多无外乎三个重点:

1、自己不熟悉的,多方面学习,接纳更成熟的方案;

2、自己要是没想好怎么做,多观察再做;

3、多思考用户场景;

我们需要考虑的场景有以下几种:

1、WHERE id = 1

{
   
    "Field": "id",
    "Operator": "Equals",
    "Value": 1
}

2、WHERE id = 1 AND id = 2

{
   
    "Logic": "And",
    "Filters":
    [
        {
   
            "Field": "id",
            "Operator": "Equals",
            "Value": 1
        },
        {
   
            "Field": "id",
            "Operator": "Equals",
            "Value": 2
        }
    ]
}

3、WHERE id IN (1,2)

{
   
    "Field": "id"

你可能感兴趣的:(.net,orm,FreeSql,.net,.net,core)