[开源] FreeSql.Tools Razor 生成器

FreeSql 通过半年的开发和坚持维护,在 0.6.x 版本中完成了几大重要事件:html

一、按小包拆分,每一个数据库实现为单独 dll;mysql

二、实现 .net framework 4.5 支持;git

三、同时支持 MySql.Data、MySqlConnector 的实现;github

四、自定义导航属性关系的配置;web

五、配套工具 FreeSql.Tools 发布;sql

本文主要讲解第5项,大主角每每在最后才出现!!!数据库

拆分小包

在此以前一直被吐槽 FreeSql 臃肿,没有小包开发理念。其实我是一点也不认可这种评价,虽然刚开发只有一个 FreeSql.dll,可是在开发和规划上简单了不少。c#

有一条开发原则讲道:过早优化是恶梦!ide

大概意思是不管作什么项目,不要想着一开始就过分系统的、规范的执行。从外界来看是正规了,可是进度和稳定性会大大折扣。能够不信我,可是请必定要相信前人的总结啊!!!工具

从以前的一个 dll 到拆分红小包,咱们总共耗时两天,虽然都在一个项目内开发,但其实耦合性并不高。

车到山前必有路,时机到了天然会拆。这个时机也是奠基 FreeSql 走出了稳定关键的一步。这样就会有更多人愿意加入 FreeSql 阵营。

  • 各数据库单独包、延时加载包;
  • FreeSql.Extensions.LazyLoading
  • FreeSql.Provider.MySql
  • FreeSql.Provider.PostgreSQL
  • FreeSql.Provider.SqlServer
  • FreeSql.Provider.Sqlite
  • FreeSql.Provider.Oracle

支持 .netframework 4.5

早期 FreeSql 主要是在 .net core 最方便的 ORM!NETStandard 是新的标准,然而前段时间微软又说 ..net5 将合并。。。变化真的太快。

在实现拆分小包后,其实 FreeSql 的模块更加清淅,而且依赖项很是之少,而后比较容易的作出了 4.5 framework 的适配。

目前支持的版本:

Package Name Version
FreeSql.Provider.MySql NETStandard2.0、net452
FreeSql.Provider.PostgreSQL NETStandard2.0、net45
FreeSql.Provider.SqlServer NETStandard2.0、net451
FreeSql.Provider.Sqlite NETStandard2.0、net45
FreeSql.Provider.Oracle NETStandard2.0、net45
FreeSql.Extensions.LazyLoading NETStandard2.0、net45

MySqlConnector 的实现

mysql 是一个神奇的流行数据库,在 .net 阵营中使用量排名老二。mysql 的版本五花八门,从 5.6 开始有了不一样的分支,分支的出现使得 ado.net 驱动不通用。

不少人不推荐使用 MySql.Data 官方驱动,可是 FreeSql 一直在使用官驱,而且支持了全部 5.6 类型,包括 enum/set 等。

而后就有一些人,特别是高手的那些来提出要求,适配一个 MySqlConnector 的实现,而后著名的 A大(茶叔)提了一道 PR ,建立了 FreeSql.Provider.MySqlConnector 项目,99.9999% 源码和原来 FreeSql.Provider.MySql 相同,通过 266 个单元测试后发现,只须要兼容 enum/set 类型,参数化 ? @ 的处理就跑通了。而后就有了如今新的驱动包:

Package Name Version
FreeSql.Provider.MySqlConnector NETStandard2.0、net45

而后 FreeSqlBuilder 使用反射决定使用哪一个 mysql 驱动。代码以下:

public IFreeSql<TMark> Build<TMark>() {
    if (string.IsNullOrEmpty(_masterConnectionString)) throw new Exception("参数 masterConnectionString 不可为空,请检查 UseConnectionString");
    IFreeSql<TMark> ret = null;
    Type type = null;
    switch(_dataType) {
        case DataType.MySql:
            type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySql")?.MakeGenericType(typeof(TMark));
            if (type == null) type = Type.GetType("FreeSql.MySql.MySqlProvider`1,FreeSql.Provider.MySqlConnector")?.MakeGenericType(typeof(TMark));
            if (type == null) throw new Exception("缺乏 FreeSql 数据库实现包:FreeSql.Provider.MySql.dll,可前往 nuget 下载");
            break;
        case DataType.SqlServer: type = Type.GetType("FreeSql.SqlServer.SqlServerProvider`1,FreeSql.Provider.SqlServer")?.MakeGenericType(typeof(TMark));
            if (type == null) throw new Exception("缺乏 FreeSql 数据库实现包:FreeSql.Provider.SqlServer.dll,可前往 nuget 下载");
            break;
        case DataType.PostgreSQL: type = Type.GetType("FreeSql.PostgreSQL.PostgreSQLProvider`1,FreeSql.Provider.PostgreSQL")?.MakeGenericType(typeof(TMark));
            if (type == null) throw new Exception("缺乏 FreeSql 数据库实现包:FreeSql.Provider.PostgreSQL.dll,可前往 nuget 下载");
            break;
        case DataType.Oracle: type = Type.GetType("FreeSql.Oracle.OracleProvider`1,FreeSql.Provider.Oracle")?.MakeGenericType(typeof(TMark));
            if (type == null) throw new Exception("缺乏 FreeSql 数据库实现包:FreeSql.Provider.Oracle.dll,可前往 nuget 下载");
            break;
        case DataType.Sqlite: type = Type.GetType("FreeSql.Sqlite.SqliteProvider`1,FreeSql.Provider.Sqlite")?.MakeGenericType(typeof(TMark));
            if (type == null) throw new Exception("缺乏 FreeSql 数据库实现包:FreeSql.Provider.Sqlite.dll,可前往 nuget 下载");
            break;
        default: throw new Exception("未指定 UseConnectionString");
    }
    ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql<TMark>;
    if (ret != null) {
        ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure;
        
        ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower;
        ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper;
        ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst;
        ret.CodeFirst.IsNoneCommandParameter = _isNoneCommandParameter;
        ret.CodeFirst.IsLazyLoading = _isLazyLoading;
        var ado = ret.Ado as Internal.CommonProvider.AdoProvider;
        ado.AopCommandExecuting += _aopCommandExecuting;
        ado.AopCommandExecuted += _aopCommandExecuted;
    }
    return ret;
}

自定义导航属性关系的配置

FreeSql 原先支持约定式导航关系配置,对于新项目开发无疑可约定,可是不少老项目命名不规范的就使用不了相关的功能。

有关约定配置可参考 github wiki 中心文档

QQ 开发群真是个好平台,在发起讨论后,各位大佬都纷纷提出建议,最后以一票否决了各大建议,哈哈。。

主要从语法和用户使用的感觉上设计,仍是那个理念:日式简约!不能加入太多特性和功能,增长用户的理解和使用成本。

最终效果以下:

//导航属性,OneToMany

[Navigate("Song_id")]
public virtual List<song_tag> Obj_song_tag { get; set; }

//导航属性,ManyToOne/OneToOne
[Navigate("Song_id")]
public virtual song Obj_song { get; set; }

[Navigate("Tag_id")]
public virtual tag Obj_tag { get; set; }

而后就能使用不少导航的骚操做功能了。

配套工具 FreeSql.Tools 发布(主角压轴)

在此感谢这个工具的做者:mypeng1985,和参考者:movingsam

感谢有大家一帮热心的使用者,帮助 FreeSql 生态添砖加瓦!!

FreeSql 在早期作过一套生成器模板,功能比较隐秘,通常人不知道如何使用。。以后就一直沉迷于 CodeFirst 的功能开发,没法自拔。

而后在10天前,忽然感受 FreeSql 多了好多使用者,这个时间固然须要有从数据库生成实体的需求了!!

Q:不必搞这种东西了吧 市面上蛮多的,或者搞一套模板彻底搞定了?

A:

  • 没法100%类型兼容啊,由于 FreeSql 支持的类型真的深,而后市场上的类型映射作不到 100% 匹配;

  • 为了挖掘更多功能,生成器还须要有导航属性的支持,这是基本的,由于有导航属性后,FreeSql 操做会骚许多;

原本我发起了一个纯 winform 的生成器项目,界面都作好了以下:

是否是以为很好看?我以为好看。。。。其余人以为丑。我在开发群发给你们看了以后,次日 FreeSql.Tools 项目就搞出了新的界面,以下:

直接被秒杀了,这是来自做者:mypeng1985 的佳做。

界面看上去很是像 web,但其实不是的,仍然是一个 winform 程序,使用了 html 作界面,c# 作操做功能。

结束语

源码地址:https://github.com/2881099/FreeSql.Tools

FreeSql 从 2018年11月28日立项,开发,到今天 0.6.x,单元测试 1600+,生态也逐渐完善,有获得许多网友的鼓励和支持,感谢大家!感谢参与项目的大家!

原文出处:https://www.cnblogs.com/FreeSql/p/10975776.html

相关文章
相关标签/搜索