欢迎访问 生活随笔!

尊龙游戏旗舰厅官网

当前位置: 尊龙游戏旗舰厅官网 > 编程语言 > asp.net >内容正文

asp.net

【纯技术贴】.netstandard freesql v0.0.9 功能预览 -尊龙游戏旗舰厅官网

发布时间:2024/10/12 asp.net 25 豆豆
尊龙游戏旗舰厅官网 收集整理的这篇文章主要介绍了 【纯技术贴】.netstandard freesql v0.0.9 功能预览 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

年关将至,尊龙游戏旗舰厅尊龙游戏旗舰厅官网首页技术含量文章真是越来越少,理解大家盼着放假过年,哥们我何尝不是,先给大家拜个早年。

兄弟我从11月底发了神经,开启了 orm 功能库的开发之旅,历时两个月编码和文档整理,目前预览版本更新到 v0.0.9 仍是一个初级版本,怎奈今天把 wiki 文档更新到一半,突然想写一篇文章提前向大家介绍项目。

快过年还逼着您来了解新的技术,实在是抱歉了。介绍一下自己,有一些朋友可能知道我本人,我经常会在群里放开源项目,比如 dotnetgen、csredis 等,反感之余仍然希望可以真的帮助到有需要的人,csrediscore 正是本人维护的项目,本文介绍的不是它。

简单点介绍,freesql 是一个netstandard orm 功能库,采用 mit 开源协议部署在 github。

  • [x] codefirst 迁移。
  • [x] dbfirst 从数据库导入实体类,支持三种模板生成器。
  • [x] 采用 expressiontree 高性能读取数据。
  • [x] 类型映射深入支持,比如pgsql的数组类型。
  • [x] 支持丰富的表达式函数。
  • [x] 支持导航属性查询,和延时加载。
  • [x] 支持同步/异步数据库操作方法,丰富多彩的链式查询方法。
  • [x] 支持事务。
  • [x] 支持读写分离。
  • [x] 支持多种数据库,mysql/sqlserver/postgresql/oracle/sqlite。
var connstr = "data source=127.0.0.1;port=3306;user id=root;password=root;" "initial catalog=cccddd;charset=utf8;sslmode=none;max pool size=10";ifreesql fsql = new freesql.freesqlbuilder().useconnectionstring(freesql.datatype.mysql, connstr).useslave("connectionstring1", "connectionstring2") //使用从数据库,支持多个.usemonitorcommand(cmd => console.writeline(cmd.commandtext), //监听sql命令对象,在执行前(cmd, tracelog) => console.writeline(tracelog)) //监听sql命令对象,在执行后.uselogger(null) //使用日志,不指定默认输出控制台 ilogger.usecache(null) //使用缓存,不指定默认使用内存 idistributedcache.useautosyncstructure(true) //自动同步实体结构到数据库.usesyncstructuretolower(true) //转小写同步结构.uselazyloading(true) //延时加载导航属性对象,导航属性需要声明 virtual.build();

可从现有数据库生成实体模型,提供 idbfirst 生成实体模型。或者手动创建模型,基于模型创建或修改数据库,提供 icodefirst 同步结构的 api(甚至可以做到开发阶段自动同步)。

[table(name = "tb_topic")] class topic {[column(isidentity = true, isprimary = true)]public int id { get; set; }public int clicks { get; set; }public int testtypeinfoguid { get; set; }public testtypeinfo type { get; set; }public string title { get; set; }public datetime createtime { get; set; } } class testtypeinfo {public int guid { get; set; }public int parentid { get; set; }public testtypeparentinfo parent { get; set; }public string name { get; set; } } class testtypeparentinfo {public int id { get; set; }public string name { get; set; } }iselect select => fsql.select();

普通查询

var sql = select.where(a => a.id == 10).tosql(); ///select ... from `tb_topic` a where (a.`id` = 10)sql = select.where(a => a.id == 10 && a.id > 10 || a.clicks > 100).tosql(); ///select ... from `tb_topic` a where (a.`id` = 10 and a.`id` > 10 or a.`clicks` > 100)sql = select.where(a => new []{1,2,3}.contains(a.id)).tosql(); //select ... from `tb_topic` a where (a.`id` in (1,2,3))

每页20条数据,查询第1页

var sql = select.page(1, 20).tosql(); ///select ... from `tb_topic` a limit 0,20

利用导航属性联表

sql = select.leftjoin(a => a.type.guid == a.testtypeinfoguid).tosql(); //select a.`id`, a.`clicks`, a.`testtypeinfoguid`, a__type.`guid`, a__type.`parentid`, a__type.`name`, a.`title`, a.`createtime` //from `tb_topic` a //left join `testtypeinfo` a__type on a__type.`guid` = a.`testtypeinfoguid`sql = select.leftjoin(a => a.type.guid == a.testtypeinfoguid).leftjoin(a => a.type.parent.id == a.type.parentid).tosql(); //select ... //from `tb_topic` a //left join `testtypeinfo` a__type on a__type.`guid` = a.`testtypeinfoguid` //left join `testtypeparentinfo` a__type__parent on a__type__parent.`id` = a__type.`parentid`

子表 exists 查询

var sql2222 = select.where(a => select.where(b => b.id == a.id).any()).tolist(); // select ... from `xxx` a where (exists(select 1 from `xxx` b where (b.`id` = a.`id`)))//两级相同的子表查询 sql2222 = select.where(a =>select.where(b => b.id == a.id && select.where(c => c.id == b.id).where(d => d.id == a.id).where(e => e.id == b.id).offset(a.id).any()).any() ).tolist(); // select ... from `xxx` a where (exists(select 1 from `xxx` b where (b.`id` = a.`id` and exists(select 1 from `xxx` c where (c.`id` = b.`id`) and (c.`id` = a.`id`) and (c.`id` = b.`id`) limit 0,1)) limit 0,1))

查找今天创建的数据

select.where(a => a.createtime.date == datetime.now.date).tosql();

支持功能丰富的表达式函数解析,包括(字符串、日期、时间、数学、类型转换)等函数,方便程序员在不了解数据库函数的情况下编写代码。这是非常特色的功能之一,深入细化函数解析尽量做到满意,所支持的类型基础都可以使用对应的表达式函数,例如 日期、字符串、in查询、数组(postgresql的数组)、字典(postgresql hstore)等等。

采用 expressiontree 优化读取速读,如果懂技术的你一定知道 .netcore 技术下除了原生代码,最快就是 emit 和 expressiontree。项目在初期使用的反射 缓存,虽然 .netcore 优化了反射性能,但经过与dapper性能测试对比之后,发现仍然有一定差距,改成 expresstiontree 后才与 dapper 性能相当。freesql 支持的类型较多,现实 expressiontree 的复杂度较大,有兴趣的朋友可以翻阅源代码。

返回单条记录

topic t1 = select.where(a => a.id == 1).toone();

freesql有两个约定,toone 永远返回 null 或 有数据的实体对象,tolist 永远返回非 null 的 list<实体类型>

返回 list

list t1 = select.where(a => a.id > 0).skip(100).limit(200).tolist();

返回 list 导航属性的数据

list t2 = select.leftjoin(a => a.type.guid == a.testtypeinfoguid).tolist(); //此时会返回普通字段 导航对象 type 的数据

指定字段返回

//返回一个字段 list t3 = select.where(a => a.id > 0).skip(100).limit(200).tolist(a => a.id);//返回匿名类 list<匿名类> t4 = select.where(a => a.id > 0).skip(100).limit(200).tolist(a => new { a.id, a.title });//返回元组 list<(int, string)> t5 = select.where(a => a.id > 0).skip(100).limit(200).tolist<(int, string)>("id, title");//返回sql字段 list<匿名类> t6 = select.where(a => a.id > 0).skip(100).limit(200).tolist(a => new {a.id,a.title,cstitle = "substr(a.title, 0, 2)", //将 substr(a.title, 0, 2) 作为查询字段csnow = convert.todatetime("now()"), //将 now() 作为查询字段//奇思妙想:怎么查询开窗函数的结果});//返回更为复杂的结构 list<匿名类> t7 = select.from((s, b, c) => s.innerjoin(a => a.typeguid == b.guid).leftjoin(a => c.id == b.parentid).where(a => b.name != "xxx")).tolist((a, b, c) => new {a.id,a.title,a.type,ccc = new { a.id, a.title },tp = a.type,tp2 = new {a.id,tp2 = a.type.name},tp3 = new {a.id,tp33 = new {a.id}}});

执行sql返回数据

class xxx {public int id { get; set; }public string path { get; set; }public string title2 { get; set; } }list t8 = fsql.ado.query("select * from song"); list<(int, string ,string)> t7 = fsql.ado.query<(int, string, string)>("select * from song"); list t9 = fsql.ado.query("select * from song");

支持 codefirst 迁移结构至数据库,这应该是(o/rm)必须标配的一个功能。

与其他(o/rm)不同freesql支持更多的数据库特性,而不只是支持基础的数据类型,这既是优点也是缺点,优点是充分利用数据库特性辅助开发,缺点是切换数据库变得困难。不同程序员的理念可能不太一致,作为功能库freesql支持到了极致,至于是否使用是项目组技术衡量的另一个问题。

尽管多种数据库适配逻辑非常复杂,freesql始终秉承优化程序开发习惯的原则尽量去现实,中间碰到了一些非技术无法攻克的难题,比如数据库的自定义类型,和实体类本身就是一种冲突,为了减少使用成本,诸如此类的数据库功能没有得到支持。

除了在实体上标注特性,也支持实体以外配置

fsql.codefirst.configentity(a => {a.name("xxdkdkdk1").selectfilter("a.id22 > 0");a.property(b => b.id).name("id22").isidentity(true);a.property(b => b.name).dbtype("varchar(100)").isnullable(true);}).configentity(a => {a.name("xxdkdkdk2").selectfilter("a.idx > 0");a.property(b => b.id).name("id22").isidentity(true);a.property(b => b.name).dbtype("varchar(100)").isnullable(true);});

类型映射

csharpmysqlsqlserverpostgresqloraclesqlite
bool | bool?bit(1)bitboolnumber(1)boolean
sbyte | sbyte?tinyint(3)smallintint2number(4)smallint
short | short?smallint(6)smallintint2number(6)smallint
int | int?int(11)intint4number(11)integer
long | long?bigint(20)bigintint8number(21)integer
byte | byte?tinyint(3) unsignedtinyintint2number(3)int2
ushort | ushort?smallint(5) unsignedintint4number(5)unsigned
uint | uint?int(10) unsignedbigintint8number(10)decimal(10,0)
ulong | ulong?bigint(20) unsigneddecimal(20,0)numeric(20,0)number(20)decimal(21,0)
double | double?doublefloatfloat8float(126)double
float | float?floatrealfloat4float(63)float
decimal | decimal?decimal(10,2)decimal(10,2)numeric(10,2)number(10,2)decimal(10,2)
guid | guid?char(36)uniqueidentifieruuidchar(36 char)character(36)
timespan | timespan?timetimetimeinterval day(2) to second(6)bigint
datetime | datetime?datetimedatetimetimestamptimestamp(6)datetime
datetimeoffset | datetimeoffset?--datetimeoffsettimestamp(6) with local time zone-
enum | enum?enumintint4number(16)mediumint
flagsenum | flagsenum?setbigintint8number(32)bigint
byte[]varbinary(255)varbinary(255)byteablobblob
stringvarchar(255)nvarchar(255)varchar(255)nvarchar2(255)nvarchar(255)
mygispointpoint----
mygislinestringlinestring----
mygispolygonpolygon----
mygismultipointmultipoint----
mygismultilinestringmultilinestring----
mygismultipolygonmultipolygon----
bitarray--varbit(64)--
npgsqlpoint--point--
npgsqlline--line--
npgsqllseg--lseg--
npgsqlbox--box--
npgsqlpath--path--
npgsqlpolygon--polygon--
npgsqlcircle--circle--
(ipaddress address, int subnet)--cidr--
ipaddress--inet--
physicaladdress--macaddr--
npgsqlrange--int4range--
npgsqlrange--int8range--
npgsqlrange--numrange--
npgsqlrange--tsrange--
postgispoint--geometry--
postgislinestring--geometry--
postgispolygon--geometry--
postgismultipoint--geometry--
postgismultilinestring--geometry--
postgismultipolygon--geometry--
postgisgeometry--geometry--
postgisgeometrycollection--geometry--
dictionary--hstore--
jtoken--jsonb--
jobject--jsonb--
jarray--jsonb--
数组--以上所有类型都支持--

以上类型和长度是默认值,可手工设置,如 string 属性可指定 [column(dbtype = "varchar(max)")]

freesql 同样支持 dbfirst 的开发模式,即先有数据库再有项目,这种传统的开发模式永远不会过时,特别适合老项目仍然在维护,或者数据库重构成本过高的项目。关系型数据库有许多成熟的运维和开发类配套工具,例如我们所关注的er图工具 powerdesigner,使用它可以更直观的查看表之间的关系。除了freesql作者同时在维护超过十年的代码生成器dotnetgen项目,它是一款支持超快速开发且高度可控的尊龙游戏旗舰厅官网的解决方案,非常喜欢 dbfirst 的开发模式,因此在 freesql for dbfirst 功能上会有不错的支持。

dbfirst 模式开发主要提供了不同数据库的表结构查询适配,配合模板生成器现实从数据库导入模型到c#代码中。

生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,实现了三种生成模板:

模板名称路径类型映射外键导航属性缓存管理失血贫血充血
simple-entity../templates/mysql/simple-entityxxxx
simple-entity-navigation-object../templates/mysql/simple-entity-navigation-objectxxx
rich-entity-navigation-object../templates/mysql/rich-entity-navigation-objectxx

项目功能与文档较多,许多细节不适合在一篇文章中展示详尽,更多的功能介绍请移步 github wiki 中心。借此文章介绍freesql这个国产orm,希望能得到大家的支持。

freesql 口号:打造 .netcore 最方便的 orm!

项目地址:https://github.com/2881099/freesql

文档中心:https://github.com/2881099/freesql/wiki

最后诚心邀请您的参与加入,一起完成 freesql 的使命。

转载于:https://www.cnblogs.com/kellynic/p/10310484.html

总结

以上是尊龙游戏旗舰厅官网为你收集整理的【纯技术贴】.netstandard freesql v0.0.9 功能预览的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得尊龙游戏旗舰厅官网网站内容还不错,欢迎将尊龙游戏旗舰厅官网推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图