在 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框架配置数据库的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持代码网。
发表评论