在 abpbase.database
中,通过 nuget 添加以下几个库:
版本都是 1.9.0-preview0917,你可以使用最新版本的。
freesql freesql.provider.sqlite freesql.provider.sqlserver freesql.provider.mysql
创建标准的 efcore 数据库上下文
在 abp 中,efcore 上下文类需要继承 abpdbcontext<t>
,整体编写方法跟继承 dbcontext<t>
一致 ,接下来我们将一步步来讲解在 abpbase
中如何添加 efcore 功能。
连接字符串
abp 中,可以在上下文类加上一个 connectionstringname
特性,然后在配置服务时,abp 会自动为其配置连接字符串。
[connectionstringname("default")] public partial class databasecontext : abpdbcontext<databasecontext>
default
是一个标识,你也可以填写其他字符串标识。
定义隔离的上下文
首先,我们在 abpbase.database
模块中,创建两个文件夹:
basedata extensiondata
basedata
目录用来存放基础表结构的上下文,extensiondata
用来存放可能会拓展或者经常变动的表结构。
在 basedata 中创建一个 abpbasedatacontext
类,其内容如下:
using microsoft.entityframeworkcore; using volo.abp.data; using volo.abp.entityframeworkcore; namespace abpbase.database { /// <summary> /// 上下文 /// <para>这部分用于定义和配置基础表的映射</para> /// </summary> [connectionstringname("default")] public partial class abpbasedatacontext : abpdbcontext<abpbasedatacontext> { #region 定义 dbset<t> #endregion public abpbasedatacontext(dbcontextoptions<abpbasedatacontext> options) : base(options) { } /// <summary> /// 定义映射 /// </summary> /// <param name="modelbuilder"></param> protected override void onmodelcreating(modelbuilder modelbuilder) { #region 定义 映射 #endregion onmodelcreatingpartial(modelbuilder); } partial void onmodelcreatingpartial(modelbuilder modelbuilder); } }
在 extensiondata 中也创建一个相同的 abpbasedatacontext
类,其内容如下:
using microsoft.entityframeworkcore; namespace abpbase.database { public partial class abpbasedatacontext { #region 定义 dbset<t> #endregion /// <summary> /// 定义映射 /// </summary> /// <param name="modelbuilder"></param> partial void onmodelcreatingpartial(modelbuilder modelbuilder) { } } }
分部类,前者用于定义那些非常基础的,程序核心的实体(表)以及映射。而后者定义后续可能多次修改的,设计时感觉有设计余地的。
多数据库支持和配置
这里我们将对上下文进行配置和注入,使得程序能够支持多数据库。
在 abpbase.domain.shared
项目中,创建一个枚举,其内容如下:
namespace abpbase.domain.shared { public enum abpbasedatatype { sqlite = 0, mysql = 1, sqlserver = 2 // 其他数据库 } }
再创建一个 wholeshared
类,其内容如下:
namespace abpbase.domain.shared { /// <summary> /// 全局共享内容 /// </summary> public static class wholeshared { // 数据库连接属性可以自行在配置文件中定义,这里写固定的,只是为了演示 /// <summary> /// 数据库连接字符串 /// </summary> public static readonly string sqlconnectstring = ""; /// <summary> /// 要使用的数据库类型 /// </summary> public static readonly abpbasedatatype datatype = abpbasedatatype.sqlite; } }
然后我们在 abpbasedatabasemodule
模块中的 configureservices
函数里面添加依赖注入:
context.services.addabpdbcontext<abpbasedatacontext>();
这里不需要配置数据库连接字符串,后面可以通过 abp 的一些方法来配置。
配置上下文连接字符串
string connectstring = default; configure<abpdbconnectionoptions>(options => { connectstring = wholeshared.sqlconnectstring; options.connectionstrings.default = connectstring; });
配置多数据库支持:
freesql.datatype datatype = default; configure<abpdbcontextoptions>(options => { switch (wholeshared.datatype) { case abpbasedatatype.sqlite: options.usesqlite<abpbasedatacontext>(); datatype = freesql.datatype.sqlite; break; case abpbasedatatype.mysql: options.usemysql<abpbasedatacontext>(); datatype = freesql.datatype.mysql; break; case abpbasedatatype.sqlserver: options.usesqlserver<abpbasedatacontext>(); datatype = freesql.datatype.sqlserver; break; } });
这样就完成了对 efcore 的多数据库配置了。
下面我们来使用类似的方法配置 freesql。
freesql 配置服务
首先,freesql 里面有多种配置方式,例如 dbcontext,读者可以到 wiki 去学习 freesql
:
https://github.com/dotnetcore/freesql/wiki/%e5%85%a5%e9%97%a8
笔者这里使用的是 “非正规” 的设计方式,哈哈哈哈。
在 basedata
目录中,创建一个 freesqlcontext
类,其内容如下:
using freesql.internal; using system; using system.collections.generic; using system.text; namespace abpbase.database { /// <summary> /// freesql 上下文 /// </summary> public partial class freesqlcontext { public static ifreesql freeselinstance => freesql_instance; private static ifreesql freesql_instance; public static void init(string connectstr, freesql.datatype datatype = freesql.datatype.sqlite) { freesql_instance = new freesql.freesqlbuilder() .usenameconvert(nameconverttype.pascalcasetounderscore) .useconnectionstring(datatype, connectstr) //.useautosyncstructure(true) // 自动同步实体结构到数据库,生产环境禁止使用! .build(); onmodelcreating(freesql_instance); } private static void onmodelcreating(ifreesql freesql) { onmodelcreatingpartial(freesql); } } }
extensiondata 目录中,创建 freesqlcontext
类 如下:
using freesql; using system; using system.collections.generic; using system.text; namespace abpbase.database { public partial class freesqlcontext { private static void onmodelcreatingpartial(ifreesql freesql) { var modelbuilder = freesql.codefirst; syncstruct(modelbuilder); } /// <summary> /// 同步结构到数据中 /// </summary> /// <param name="codefirst"></param> private static void syncstruct(icodefirst codefirst) { // codefirst.syncstructure(typeof(user)); } } }
然后在 abpbasedatabasemodule
的 configureservices
函数中添加注入服务:
freesqlcontext.init(connectstring, datatype); context.services.addsingleton(typeof(ifreesql), freesqlcontext.freeselinstance); context.services.addtransient(typeof(freesqlcontext), typeof(freesqlcontext));
通过以上步骤,我们的 abp 就可以支持多数据库了,efcore + freesql,并且将将表分级隔离维护。
到此这篇关于为abp框架配置数据库的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持代码网。
发表评论