.NETStandard FreeSql v0.0.9 功能预览
年關(guān)將至,首頁技術(shù)含量文章真是越來越少,理解大家盼著放假過年,哥們我何嘗不是,先給大家拜個(gè)早年。
兄弟我從11月底發(fā)了神經(jīng),開啟了 ORM 功能庫的開發(fā)之旅,歷時(shí)兩個(gè)月編碼和文檔整理,目前預(yù)覽版本更新到 v0.0.9 仍是一個(gè)初級(jí)版本,怎奈今天把 wiki 文檔更新到一半,突然想寫一篇文章提前向大家介紹項(xiàng)目。
快過年還逼著您來了解新的技術(shù),實(shí)在是抱歉了。介紹一下自己,有一些朋友可能知道我本人,我經(jīng)常會(huì)在群里放開源項(xiàng)目,比如 dotnetGen、csredis 等,反感之余仍然希望可以真的幫助到有需要的人,CSRedisCore 正是本人維護(hù)的項(xiàng)目,本文介紹的不是它。
簡(jiǎn)單點(diǎn)介紹,FreeSql 是一個(gè)NETStandard ORM 功能庫,采用 MIT 開源協(xié)議部署在 github。
它實(shí)現(xiàn)了的功能特性
[x] CodeFirst 遷移。
[x] DbFirst 從數(shù)據(jù)庫導(dǎo)入實(shí)體類,支持三種模板生成器。
[x] 采用 ExpressionTree 高性能讀取數(shù)據(jù)。
[x] 類型映射深入支持,比如pgsql的數(shù)組類型。
[x] 支持豐富的表達(dá)式函數(shù)。
[x] 支持導(dǎo)航屬性查詢,和延時(shí)加載。
[x] 支持同步/異步數(shù)據(jù)庫操作方法,豐富多彩的鏈?zhǔn)讲樵兎椒ā?/p>
[x] 支持事務(wù)。
[x] 支持讀寫分離。
[x] 支持多種數(shù)據(jù)庫,MySql/SqlServer/PostgreSQL/Oracle/Sqlite。
快速開始
定義實(shí)體
可從現(xiàn)有數(shù)據(jù)庫生成實(shí)體模型,提供 IDbFirst 生成實(shí)體模型。或者手動(dòng)創(chuàng)建模型,基于模型創(chuàng)建或修改數(shù)據(jù)庫,提供 ICodeFirst 同步結(jié)構(gòu)的 API(甚至可以做到開發(fā)階段自動(dòng)同步)。
查詢
普通查詢
每頁20條數(shù)據(jù),查詢第1頁
var sql = select.Page(1, 20).ToSql();///SELECT ... FROM `tb_topic` a LIMIT 0,20利用導(dǎo)航屬性聯(lián)表
子表 Exists 查詢
查找今天創(chuàng)建的數(shù)據(jù)
select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToSql();支持功能豐富的表達(dá)式函數(shù)解析,包括(字符串、日期、時(shí)間、數(shù)學(xué)、類型轉(zhuǎn)換)等函數(shù),方便程序員在不了解數(shù)據(jù)庫函數(shù)的情況下編寫代碼。這是非常特色的功能之一,深入細(xì)化函數(shù)解析盡量做到滿意,所支持的類型基礎(chǔ)都可以使用對(duì)應(yīng)的表達(dá)式函數(shù),例如 日期、字符串、IN查詢、數(shù)組(PostgreSQL的數(shù)組)、字典(PostgreSQL HStore)等等。
獲得查詢返回的數(shù)據(jù)
采用 ExpressionTree 優(yōu)化讀取速讀,如果懂技術(shù)的你一定知道 .NETCore 技術(shù)下除了原生代碼,最快就是 Emit 和 ExpressionTree。項(xiàng)目在初期使用的反射+緩存,雖然 .NETCore 優(yōu)化了反射性能,但經(jīng)過與Dapper性能測(cè)試對(duì)比之后,發(fā)現(xiàn)仍然有一定差距,改成 ExpresstionTree 后才與 Dapper 性能相當(dāng)。FreeSql 支持的類型較多,現(xiàn)實(shí) ExpressionTree 的復(fù)雜度較大,有興趣的朋友可以翻閱源代碼。
返回單條記錄
Topic t1 = select.Where(a => a.Id == 1).ToOne();FreeSql有兩個(gè)約定,ToOne 永遠(yuǎn)返回 null 或 有數(shù)據(jù)的實(shí)體對(duì)象,ToList 永遠(yuǎn)返回非 null 的 List<實(shí)體類型>
返回 List
List<Topic> t1 = select.Where(a => a.Id > 0).Skip(100).Limit(200).ToList();返回 List + 導(dǎo)航屬性的數(shù)據(jù)
List<Topic> t2 = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid).ToList();//此時(shí)會(huì)返回普通字段 + 導(dǎo)航對(duì)象 Type 的數(shù)據(jù)指定字段返回
執(zhí)行SQL返回?cái)?shù)據(jù)
CodeFirst
支持 CodeFirst 遷移結(jié)構(gòu)至數(shù)據(jù)庫,這應(yīng)該是(O/RM)必須標(biāo)配的一個(gè)功能。
與其他(O/RM)不同F(xiàn)reeSql支持更多的數(shù)據(jù)庫特性,而不只是支持基礎(chǔ)的數(shù)據(jù)類型,這既是優(yōu)點(diǎn)也是缺點(diǎn),優(yōu)點(diǎn)是充分利用數(shù)據(jù)庫特性輔助開發(fā),缺點(diǎn)是切換數(shù)據(jù)庫變得困難。不同程序員的理念可能不太一致,作為功能庫FreeSql支持到了極致,至于是否使用是項(xiàng)目組技術(shù)衡量的另一個(gè)問題。
盡管多種數(shù)據(jù)庫適配邏輯非常復(fù)雜,FreeSql始終秉承優(yōu)化程序開發(fā)習(xí)慣的原則盡量去現(xiàn)實(shí),中間碰到了一些非技術(shù)無法攻克的難題,比如數(shù)據(jù)庫的自定義類型,和實(shí)體類本身就是一種沖突,為了減少使用成本,諸如此類的數(shù)據(jù)庫功能沒有得到支持。
除了在實(shí)體上標(biāo)注特性,也支持實(shí)體以外配置
類型映射
| bool | bool? | bit(1) | bit | bool | number(1) | boolean |
| sbyte | sbyte? | tinyint(3) | smallint | int2 | number(4) | smallint |
| short | short? | smallint(6) | smallint | int2 | number(6) | smallint |
| int | int? | int(11) | int | int4 | number(11) | integer |
| long | long? | bigint(20) | bigint | int8 | number(21) | integer |
| byte | byte? | tinyint(3) unsigned | tinyint | int2 | number(3) | int2 |
| ushort | ushort? | smallint(5) unsigned | int | int4 | number(5) | unsigned |
| uint | uint? | int(10) unsigned | bigint | int8 | number(10) | decimal(10,0) |
| ulong | ulong? | bigint(20) unsigned | decimal(20,0) | numeric(20,0) | number(20) | decimal(21,0) |
| double | double? | double | float | float8 | float(126) | double |
| float | float? | float | real | float4 | float(63) | float |
| decimal | decimal? | decimal(10,2) | decimal(10,2) | numeric(10,2) | number(10,2) | decimal(10,2) |
| Guid | Guid? | char(36) | uniqueidentifier | uuid | char(36 CHAR) | character(36) |
| TimeSpan | TimeSpan? | time | time | time | interval day(2) to second(6) | bigint |
| DateTime | DateTime? | datetime | datetime | timestamp | timestamp(6) | datetime |
| DateTimeOffset | DateTimeOffset? | - | - | datetimeoffset | timestamp(6) with local time zone | - |
| Enum | Enum? | enum | int | int4 | number(16) | mediumint |
| FlagsEnum | FlagsEnum? | set | bigint | int8 | number(32) | bigint |
| byte[] | varbinary(255) | varbinary(255) | bytea | blob | blob |
| string | varchar(255) | nvarchar(255) | varchar(255) | nvarchar2(255) | nvarchar(255) |
| MygisPoint | point | - | - | - | - |
| MygisLineString | linestring | - | - | - | - |
| MygisPolygon | polygon | - | - | - | - |
| MygisMultiPoint | multipoint | - | - | - | - |
| MygisMultiLineString | multilinestring | - | - | - | - |
| MygisMultiPolygon | multipolygon | - | - | - | - |
| BitArray | - | - | varbit(64) | - | - |
| NpgsqlPoint | NpgsqlPoint? | - | - | point | - | - |
| NpgsqlLine | NpgsqlLine? | - | - | line | - | - |
| NpgsqlLSeg | NpgsqlLSeg? | - | - | lseg | - | - |
| NpgsqlBox | NpgsqlBox? | - | - | box | - | - |
| NpgsqlPath | NpgsqlPath? | - | - | path | - | - |
| NpgsqlPolygon | NpgsqlPolygon? | - | - | polygon | - | - |
| NpgsqlCircle | NpgsqlCircle? | - | - | circle | - | - |
| (IPAddress Address, int Subnet) | (IPAddress Address, int Subnet)? | - | - | cidr | - | - |
| IPAddress | - | - | inet | - | - |
| PhysicalAddress | - | - | macaddr | - | - |
| NpgsqlRange<int> | NpgsqlRange<int>? | - | - | int4range | - | - |
| NpgsqlRange<long> | NpgsqlRange<long>? | - | - | int8range | - | - |
| NpgsqlRange<decimal> | NpgsqlRange<decimal>? | - | - | numrange | - | - |
| NpgsqlRange<DateTime> | NpgsqlRange<DateTime>? | - | - | tsrange | - | - |
| PostgisPoint | - | - | geometry | - | - |
| PostgisLineString | - | - | geometry | - | - |
| PostgisPolygon | - | - | geometry | - | - |
| PostgisMultiPoint | - | - | geometry | - | - |
| PostgisMultiLineString | - | - | geometry | - | - |
| PostgisMultiPolygon | - | - | geometry | - | - |
| PostgisGeometry | - | - | geometry | - | - |
| PostgisGeometryCollection | - | - | geometry | - | - |
| Dictionary<string, string> | - | - | hstore | - | - |
| JToken | - | - | jsonb | - | - |
| JObject | - | - | jsonb | - | - |
| JArray | - | - | jsonb | - | - |
| 數(shù)組 | - | - | 以上所有類型都支持 | - | - |
以上類型和長(zhǎng)度是默認(rèn)值,可手工設(shè)置,如 string 屬性可指定 [Column(DbType = "varchar(max)")]
DbFirst
FreeSql 同樣支持 DbFirst 的開發(fā)模式,即先有數(shù)據(jù)庫再有項(xiàng)目,這種傳統(tǒng)的開發(fā)模式永遠(yuǎn)不會(huì)過時(shí),特別適合老項(xiàng)目仍然在維護(hù),或者數(shù)據(jù)庫重構(gòu)成本過高的項(xiàng)目。關(guān)系型數(shù)據(jù)庫有許多成熟的運(yùn)維和開發(fā)類配套工具,例如我們所關(guān)注的ER圖工具 PowerdeSigner,使用它可以更直觀的查看表之間的關(guān)系。除了FreeSql作者同時(shí)在維護(hù)超過十年的代碼生成器dotnetGen項(xiàng)目,它是一款支持超快速開發(fā)且高度可控的解決方案,非常喜歡 DbFirst 的開發(fā)模式,因此在 FreeSql for DbFirst 功能上會(huì)有不錯(cuò)的支持。
DbFirst 模式開發(fā)主要提供了不同數(shù)據(jù)庫的表結(jié)構(gòu)查詢適配,配合模板生成器現(xiàn)實(shí)從數(shù)據(jù)庫導(dǎo)入模型到c#代碼中。
生成器是基于 DbFirst 開發(fā)的輔助工具,適用老項(xiàng)目一鍵生成實(shí)體。生成器采用模板的方式,實(shí)現(xiàn)了三種生成模板:
| simple-entity | ../Templates/MySql/simple-entity | √ | X | X | √ | X | X |
| simple-entity-navigation-object | ../Templates/MySql/simple-entity-navigation-object | √ | √ | X | √ | X | X |
| rich-entity-navigation-object | ../Templates/MySql/rich-entity-navigation-object | √ | √ | √ | X | √ | X |
結(jié)語
項(xiàng)目功能與文檔較多,許多細(xì)節(jié)不適合在一篇文章中展示詳盡,更多的功能介紹請(qǐng)移步 github wiki 中心。借此文章介紹FreeSql這個(gè)國(guó)產(chǎn)ORM,希望能得到大家的支持。
FreeSql 口號(hào):打造 .NETCore 最方便的 ORM!
項(xiàng)目地址:https://github.com/2881099/FreeSql
文檔中心:https://github.com/2881099/FreeSql/wiki
最后誠(chéng)心邀請(qǐng)您的參與加入,一起完成 FreeSql 的使命。
原文地址:https://www.cnblogs.com/kellynic/p/10310484.html
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號(hào)文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的.NETStandard FreeSql v0.0.9 功能预览的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在AspNetMvc中使用日志面板. L
- 下一篇: SeaweedFS在.net core下