年關將至,首頁技術含量文章真是越來越少,理解大家盼著放假過年,哥們我何嘗不是,先給大家拜個早年。
兄弟我從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。
快速開始
定義物體
可從現有資料庫生成物體模型,提供 IDbFirst 生成物體模型。或者手動建立模型,基於模型建立或修改資料庫,提供 ICodeFirst 同步結構的 API(甚至可以做到開發階段自動同步)。
查詢
普通查詢
每頁20條資料,查詢第1頁
var sql = select.Page(1, 20).ToSql();///SELECT ... FROM `tb_topic` a LIMIT 0,20
利用導航屬性聯表
子表 Exists 查詢
查詢今天建立的資料
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 的資料
指定欄位傳回
執行SQL傳回資料
CodeFirst
支援 CodeFirst 遷移結構至資料庫,這應該是(O/RM)必須標配的一個功能。
與其他(O/RM)不同FreeSql支援更多的資料庫特性,而不只是支援基礎的資料型別,這既是優點也是缺點,優點是充分利用資料庫特性輔助開發,缺點是切換資料庫變得困難。不同程式員的理念可能不太一致,作為功能庫FreeSql支援到了極致,至於是否使用是專案組技術衡量的另一個問題。
儘管多種資料庫適配邏輯非常複雜,FreeSql始終秉承最佳化程式開發習慣的原則儘量去現實,中間碰到了一些非技術無法攻剋的難題,比如資料庫的自定義型別,和物體類本身就是一種衝突,為了減少使用成本,諸如此類的資料庫功能沒有得到支援。
除了在物體上標註特性,也支援物體以外配置
型別對映
csharp | MySql | SqlServer | PostgreSQL | Oracle | Sqlite |
---|---|---|---|---|---|
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 | NpgsqlRange? | – | – | int4range | – | – |
NpgsqlRange | NpgsqlRange? | – | – | int8range | – | – |
NpgsqlRange | NpgsqlRange? | – | – | numrange | – | – |
NpgsqlRange | 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)”)]
DbFirst
FreeSql 同樣支援 DbFirst 的開發樣式,即先有資料庫再有專案,這種傳統的開發樣式永遠不會過時,特別適合老專案仍然在維護,或者資料庫重構成本過高的專案。關係型資料庫有許多成熟的運維和開發類配套工具,例如我們所關註的ER圖工具 PowerdeSigner,使用它可以更直觀的查看錶之間的關係。除了FreeSql作者同時在維護超過十年的程式碼生成器dotnetGen專案,它是一款支援超快速開發且高度可控的解決方案,非常喜歡 DbFirst 的開發樣式,因此在 FreeSql for DbFirst 功能上會有不錯的支援。
DbFirst 樣式開發主要提供了不同資料庫的表結構查詢適配,配合模板生成器現實從資料庫匯入模型到c#程式碼中。
生成器是基於 DbFirst 開發的輔助工具,適用老專案一鍵生成物體。生成器採用模板的方式,實現了三種生成模板:
模板名稱 | 路徑 | 型別對映 | 外來鍵導航屬性 | 快取管理 | 失血 | 貧血 | 充血 |
---|---|---|---|---|---|---|---|
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 |
結語
專案功能與檔案較多,許多細節不適合在一篇文章中展示詳盡,更多的功能介紹請移步 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