扩展-数据库种类
ClownFish只支持几种常用数据库,如果没有你需要的数据库,请自行扩展。
本文演示对 人大金仓-KingbaseES 数据库的支持
引用数据库驱动包
首先我们引用官方的客户端驱动
<ItemGroup>
<PackageReference Include="Kdbndp_V9" Version="8.0.1.906" />
</ItemGroup>
实现 BaseClientProvider 抽象类
完整代码如下:
public class KingbaseESClientProvider : BaseClientProvider
{
public static readonly BaseClientProvider Instance = new KingbaseESClientProvider();
#region 定义2个"常量",可以避免在其它代码中出现“硬编码”。
public static readonly string ProviderName = "Kdbndp";
// 由于 DatabaseType 是枚举,无法扩展,所以只能使用“强转”方式
public static readonly DatabaseType DatabaseTypeKingbaseES = (DatabaseType)7777;
#endregion
public static void RegisterProvider()
{
// Npgsql 6.0 对时间戳的映射方式进行了一些重要更改
// https://www.npgsql.org/doc/types/datetime.html#timestamps-and-timezones
AppContext.SetSwitch("Kdbndp.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Kdbndp.DisableDateTimeInfinityConversions", true);
DbClientFactory.RegisterProvider(ProviderName, Instance);
}
public override DatabaseType DatabaseType => DatabaseTypeKingbaseES;
public override DbProviderFactory ProviderFactory => Kdbndp.KdbndpFactory.Instance;
public override string GetObjectFullName(string symbol)
{
// https://help.kingbase.com.cn/v8/faq/faq-new/sql.html#id12
return "\"" + symbol + "\"";
}
public override CPQuery GetNewIdQuery(CPQuery query, object entity)
{
return query + "; SELECT lastval();"; // 参考 PostgreSql 的实现
}
public override bool IsDuplicateInsertException(Exception ex)
{
if( ex is Kdbndp.KingbaseException ex2 ) {
return ex2.SqlState == "23505"; // 参考 PostgreSql 的实现
}
return false;
}
public override CPQuery SetPagedQuery(CPQuery query, int skip, int take)
{
return StdClientProvider.SetPagedQuery(query, skip, take);
}
public override Page2Query GetPagedCommand(BaseCommand query, PagingInfo pagingInfo)
{
return StdClientProvider.GetPagedCommand(query, pagingInfo);
}
public override string GetConnectionString(IDbConfig dbConfig, bool includeDatabase)
{
return PostgreSqlClientProvider.GetPostgreSQLConnectionString0(dbConfig, includeDatabase);
}
}
初始化
在程序启动过程中,
ClownFishInit.InitDAL();
// 在 InitDAL 之后调用
KingbaseESClientProvider.RegisterProvider();
配置连接
<configuration>
<connectionStrings>
<add name="kingbase2" providerName="Kdbndp"
connectionString="Host=192.168.1.1;database=mynorthwind;port=34321;Username=sa;Password=xxxxxxx"/>
</connectionStrings>
<dbConfigs>
<add name="kingbase3" dbType="7777" server="192.168.1.1" port="34321" database="mynorthwind" uid="sa" pwd="xxxxxxx" args="" />
</dbConfigs>
</configuration>
说明:
- 连接名“kingbase2”,设置了 providerName="Kdbndp"
- 这是调用 DbClientFactory.RegisterProvider方法的第一个参数
- 连接名“kingbase3”,设置了 dbType="7777"
- 它是 KingbaseESClientProvider.DatabaseType 的返回结果
测试代码
using( DbContext db = DbContext.Create("kingbase2") ) {
// 确认此DbContext实例将会使用 KingbaseESClientProvider
Assert.AreEqual(KingbaseESClientProvider.DatabaseTypeKingbaseES, db.DatabaseType);
Assert.AreEqual(KingbaseESClientProvider.ProviderName, db.ProviderName);
long id = db.CPQuery.Create("select max(productid) from products").ExecuteScalar<long>();
Assert.IsTrue(id > 0);
}
using( DbContext db = DbContext.Create("kingbase3") ) {
Assert.AreEqual(KingbaseESClientProvider.DatabaseTypeKingbaseES, db.DatabaseType);
Assert.AreEqual(KingbaseESClientProvider.ProviderName, db.ProviderName);
long id = db.CPQuery.Create("select max(productid) from products").ExecuteScalar<long>();
Assert.IsTrue(id > 0);
}