FreeSql 新的八大騷功能,.NETCore 你必須曉得的 ORM

前言

FreeSql 目前版本號 0.5.5,預計明年元旦發佈 1.0.0,切莫小看了版本號,目前單元測試方法1350+,而且每一個方法內的涵蓋面又比較廣(不信的話見下圖),每一次版本發佈都做了較多的測試工做。前端

最近的一段時間,關注咱們的人時不時會看見擴展包發佈,今天振奮人心的功能主要是核心部分實現(擴展包今天當配角)。就很少囉嗦了,我們直接入主題。git

功能一:MapType 類型映射

使用 codefirst 時序列化 json 或 jsonb 數據類型報錯

使用 postgresql + ef 配置數據映射關係,使用 FreeSql 的映射擴展時,對於json類型的數據映射出錯。github

這是來自 github 上的某個 issue,緣由是用戶的實體定義了 string,數據庫類型爲 json。FreeSql 自己支持了豐富的類型,不限於 json,可是限定了類型的映射,好比 JToken/JObject/JArray 的實體類型才能夠映射至 PostgreSQL 數據庫的 json 類型。另外雖然有 DbType 特性能夠設置,但使用範圍有限,不可跨越類型(如使用 string 可以使用 DbType="char(100)")。sql

還有一些相似要求,如:將 enum 映射到數據庫 varchar 的請求。。。。數據庫

到如今,咱們已經完全突破了這個障礙,基本能夠作到隨意映射類型。做爲新項目開發,咱們提供自己的默認類型映射已經很是人性化,提這些需求的人主要仍是歷史緣由,我們作程序維護工做的人員仍是佔比很高,千怪萬怪只能怪 FreeSql 來得太遲。。。。json

目前爲 MapType 功能增長了大約 400 個單元測試方法。貼一段 demo 配置方法:c#

class EnumTestMap {
    public Guid id { get; set; }

    [Column(MapType = typeof(string))]
    public ToStringMapEnum enum_to_string { get; set; }
    [Column(MapType = typeof(string))]
    public ToStringMapEnum? enumnullable_to_string { get; set; }

    [Column(MapType = typeof(int))]
    public ToStringMapEnum enum_to_int { get; set; }
    [Column(MapType = typeof(int?))]
    public ToStringMapEnum? enumnullable_to_int { get; set; }

    [Column(MapType = typeof(string))]
    public BigInteger biginteger_to_string { get; set; }
    [Column(MapType = typeof(string))]
    public BigInteger? bigintegernullable_to_string { get; set; }
}
public enum ToStringMapEnum { 中國人, abc, 香港 }

應該不須要解釋了吧?數組

細看一下,實體內有 BigInteger 類型,這但是數據庫沒法表示的類型,如今就是可使用(沒轍)。但請注意:BigInteger 僅僅是 CURD 方便, Equals == 判斷可使用,沒法使用 + - * / < > 等操做;安全

默認映射

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<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 - -
數組 - - 以上全部類型都支持 - -
以上類型和長度是默認值,可手工設置,如 string 屬性可指定 [Column(DbType = "varchar(max)")]

功能二:惟一鍵(Unique)

class AddUniquesInfo {

    public Guid id { get; set; }
    [Column(Unique = "uk_phone")]
    public string phone { get; set; }

    [Column(Unique = "uk_group_index")]
    public string group { get; set; }
    [Column(Unique = "uk_group_index")]
    public int index { get; set; }

    [Column(Unique = "uk_group_index222")]
    public string index22 { get; set; }
}

Unique 指定相同的標識,表明聯合惟一鍵,現已支持遷移。前端框架

功能三:弱類型(實體)

以前在操做實體時,必須傳統泛型參數,如今能夠實現弱類型實體的操做。以 Repository 爲例:

var repos = fsql.GetGuidRepository<object>();
repos.AsType(typeof(AddUpdateInfo));

var item = new AddUpdateInfo();
repos.Insert(item);

item.Clicks += 1;
repos.InsertOrUpdate(item);

var item2 = repos.Find(item.Id) as AddUpdateInfo;
Assert.Equal(item.Clicks, item2.Clicks);

repos.DataFilter.Apply("xxx", a => (a as AddUpdateInfo).Clicks == 11);
Assert.Null(repos.Find(item.Id));

而後呢,DbContext 也支持一樣的操做。

dotnet add package FreeSql.DbContext

功能四:ToList & Mapper

如今支持 ToList(a => new Dto()) 這樣的簡單數據映射。

什麼意思?即 Dto 只要有屬性名與實體屬性相同,就會根據匹配到的字段查詢(不是查詢全部字段回來再映射)。

而後這個騷操做,還支持多表查詢的映射,怎麼解決多表存在相同名字的字段問題呢?優先級規則,它會依次序匹配 LeftJoin/InnerJoin/RightJoin 的實體。

功能五:ToList(true) 貪婪加載

之前 .ToList() 會加載兩級Join對象;

如今 ISelect.ToList(includeNestedMembers: true) 貪婪加載全部 LeftJoin/InnerJoin/RightJoin 導航數據,不論對象的層級;

功能六:WhereDynamic 動態條件

支持傳入動態對象如:主鍵值 | new[]{主鍵值1,主鍵值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}。

也就是說 WhereDynaimc 方法輸入類型爲 object,是否是很方便?還支持聯合主鍵呢。

功能七:IAdo.Query 多個結果集

var result = fsql.Ado.Query<T1, T2>("select from t1; select from t2");

功能八:開發環境之利器:MVC 中間件 FreeSql.AdminLTE

大約是前一段時間的某一天(廢話),由於使用 FreeSql 的某項目須要作一個簡單的後臺功能,以便錄入或管理數據。在實施的過程當中好懷念當初 dotnetGen 生成器的味道,用它產生 curd 基本功能幾乎是秒作;

FreeSql.AdminLTE,是的就是它,前段時間發佈過一次。

它是 FreeSql 衍生出來的 .NETCore MVC 中間件、中間件、中間件(重複三遍)擴展包,基於 AdminLTE 前端框架動態產生實體的增刪查改界面;

輸入:實體一、實體二、實體3

輸出:後臺管理的功能

只須要傳入實體,就能夠造成 curd 的管理功能,是否是有些騷啊~~~

先發一張運行後的圖片嚐個鮮:

這是根據實體產生 curd 界面的 mvc 中間件,開發時預覽數據好方便啊。看完預覽圖不禁得再感嘆一次 FreeSql 的易用性,那句口號:作 .NETCore 最方便的 ORM! 沒有說錯。。。做者屢次說起:「咱們是日式簡約風格,沒那麼複雜的用法」,也驗證了這一點。。

添加/修改

中件間產生的界面包括添加、修改數據的功能,普通實體的根據屬性的類型與 Html5 UI 一一映射;

比較特殊的映射規則:

c# 類型 Html5
布爾 複選框
枚舉 下拉選擇
日期 日期控件
ManyToOne 導航屬性 下拉選擇
ManyToMany 導航屬性 多選器

等等。。。

什麼狀況會產生【上傳文件】控件?
有興趣的能夠了解源碼,目前沒有開放在外部配置。

查詢/過濾

中件間爲每一個實體提供了分頁列表查詢,每頁爲20條數據;

除此外,還提供了過濾條件的支持,規則是根據導航屬性(ManyToOne、ManyToMany)。好比【文章實體】,內含有【分類id】+【分類對象】,則【文章】列表頁會出現按【分類】篩選的UI,詳見上面的 demo 示意圖,或者下載對應的 demo 版本運行;

刪除

中件間爲每一個實體提供了批量刪除的功能;

測試 demo

咱們習慣用 sqlite 作測試庫,測試完畢直接刪除目錄,不留垃圾數據,因此下面的 demo 不須要修改任何地方,運行時自動建庫、建表;

提供 .net core 2.一、2.2 兩種環境的測試 demo 下載:

Demo for dotnet 2.1.zipDemo for dotnet 2.2.zip

image

第一步:

dotnet restore

第二步:

dotnet run

思考

一番驚喜事後,你應該會考慮實用性,這樣作有什麼價值,可用於什麼樣的場景?

這個擴展包簡單的輸入,產生巨量的功能反饋。目前來講它是死板的,對外提供的擴展性幾乎爲零,這樣也就限定了它的應用場景。

不合適的場景

一、它不可替代咱們自身開發的後臺管理系統;

二、它不適合擺放在公網正式環境,存在數據安全問題;

三、歡迎補充。。。;

談談定位

目前的定位是這樣的,在開發環境中使用,查閱預覽實體數據,同時也比較方便的管理測試數據。

一段擁有無比力量的小段代碼,也是中間件界面的功能開啓:

//能夠配置子目錄訪問,如:/testadmin/
app.UseFreeAdminLTE("/",
    typeof(Entities.Song),
    typeof(Entities.Tag));

觀後抽獎

咱們一直在發佈純技術乾貨的分享文章,FreeSql 已經基本完成 .NETCore 最方便的 ORM 使命,咱們正在籌備生態的創建,好比 ABP 中如何使用 FreeSql 的實現,須要各類各樣的擴展包,好多好多工做量。有沒有大神願意無償參與作這件事情,好吧。。應該沒有人!!若是你回心轉意了,歡迎聯繫咱們。

歡迎持續關注咱們,作 .NETCore 最方便的 ORM !

(QQ羣:4336577)

github: https://github.com/2881099/FreeSql

說好的抽獎呢???

相關文章
相關標籤/搜索