FreeSql 新的八大骚功能,.NETCore 你必须晓得的 ORM

前言

FreeSql 目前版本号 0.5.5,预计明年元旦发布 1.0.0,切莫小看了版本号,目前单元测试方法1350+,而且每一个方法内的涵盖面又比较广(不信的话见下图),每一次版本发布都做了较多的测试工做。前端

最近的一段时间,关注咱们的人时不时会看见扩展包发布,今天振奋人心的功能主要是核心部分实现(扩展包今天当配角)。就很少啰嗦了,我们直接入主题。git

功能一:MapType 类型映射

使用 codefirst 时序列化 json 或 jsonb 数据类型报错github

使用 postgresql + ef 配置数据映射关系,使用 FreeSql 的映射扩展时,对于json类型的数据映射出错。sql

这是来自 github 上的某个 issue,缘由是用户的实体定义了 string,数据库类型为 json。FreeSql 自己支持了丰富的类型,不限于 json,可是限定了类型的映射,好比 JToken/JObject/JArray 的实体类型才能够映射至 PostgreSQL 数据库的 json 类型。另外虽然有 DbType 特性能够设置,但使用范围有限,不可跨越类型(如使用 string 可以使用 DbType="char(100)")。数据库

还有相似的,如:将 enum 映射到数据库 varchar 的请求。。。。json

到如今,咱们已经完全突破了这个障碍,基本能够作到随意映射类型。做为新项目开发,咱们提供自己的默认类型映射已经很是人性化,提这些需求的人主要仍是历史缘由,我们作程序维护工做的人员仍是占比很高,千怪万怪只能怪 FreeSql 来得太迟。。。。c#

目前为 MapType 功能增长了大约 400 个单元测试方法。贴一段 demo 配置方法:数组

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, int)
(IPAddress, int)?
- - 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 贪婪加载

之前 .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

说好的抽奖呢???

相关文章
相关标签/搜索