由于我们有时候需要在基于.net framework的项目上使用(如Winform端应用),有时候有需要在.net core的项目上使用(如.net core的WebAPI),那么我们把基于SQLSugar的基础模块封装,编译为.net standard就很有必要,而且由于.net framework和.net core在配置文件上的差异,我们需要对基础配置信息进行不同环境的兼容处理,以便实现基础模块支持.net FrameWork和.net core的项目调用。

1、基于.netStandard的类库模块

在上篇随笔《基于SqlSugar的数据库访问处理的封装,支持多数据库并使之适应于实际业务开发中(1)》中介绍了对SqlSugar 基础模块的封装处理,为了兼容不同类型的框架,我们可以把它们封装为.net Standard类库。

但是 为了基础模块能够顺利加载不同.net框架下的配置文件信息来初始化数据库连接,我们需要配置不同的加载处理方式来读取处理。

如.net Framework的使用App.config中读取配置信息,而.net core项目中使用读取 appSettings.json里面的配置信息。

因此需要让它们兼容,我们需要修改项目文件中的TargetFrameworks,让它根据不同的框架生成不同的DLL类库,从而达到支持不同环境下配置文件的读取处理。

这样我们查看项目属性,就可以看到类库是支持多种目标框架的了。

接下来我们对DbContext辅助类进行改动,让它根据不同的目标框架条件来读取配置信息。

统一入口就是调用ConfigHelper辅助类来隔离处理操作。

        public DbContext()
{
this.DbSetting = ConfigHelper.GetDbSettings();
Init(this.DbSetting.DbConfigName);
} public DbContext(string dbConfigName)
{
if (this.DbSetting == null)
{
this.DbSetting = ConfigHelper.GetDbSettings();
}
Init(dbConfigName);
}

以替代原先的处理代码。原先的只能从.net framework的App.config中读取,现在我们需要根据框架来判断处理。

        public DbContext()
{
//默认采用配置项名
//appSettings/DefaultDb 配置项为指定连接字符串的name
var dbConfigName = ConfigurationManager.AppSettings["DefaultDb"];
Init(dbConfigName);
}

我们先来定义一个承载数据库信息的实体类对象。

    /// <summary>
/// 数据库配置信息
/// </summary>
public class DbSetting
{
/// <summary>
/// 默认指定的连接字符串集合的配置项名称
/// </summary>
public string DbConfigName { get; set; } /// <summary>
/// 数据库类型,默认为SQLServer
/// </summary>
public string DbType { get; set; } = "sqlserver"; /// <summary>
/// 连接字符串
/// </summary>
public string ConnectionString { get; set; } }

在目标框架为.net framwork的时候,我们的App.Config配置信息是下面的。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<!--Sqlserver数据库的连接字符串-->
<add name="sqlserver" providerName="System.Data.SqlClient" connectionString="Persist Security Info=False;Data Source=(local);Initial Catalog=WinFramework;Integrated Security=SSPI" />
<!--MySQL数据库的连接字符串-->
<add name="mysql" providerName="MySql.Data.MySqlClient" connectionString="Server=localhost;Database=winframework;Uid=root;Pwd=123456;SslMode=none" />
<!--sqlite数据库字符串,路径符号|DataDirectory|代表当前运行目录-->
<add name="sqlite" providerName="System.Data.SQLite" connectionString="Data Source=|DataDirectory|\WinFramework.db;Version=3;" />
<!--PostgreSQL数据库的连接字符串-->
<add name="npgsql" providerName="Npgsql" connectionString="Server=localhost;Port=5432;Database=winframework;User Id=postgres;Password=123456" />
<!--不受驱动影响,32位64位均可使用-->
<add name="oracle" providerName="OracleManaged" connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)));User ID=win;Password=win" />
<!--达梦数据库的连接字符串-->
<add name="Dm" providerName="Dm" connectionString="Server=localhost;User ID=SYSDBA;PWD=SYSDBA;Database=WINFRAMEWORK;" />
</connectionStrings> <appSettings>
<!--指定默认的数据库类型,如果不指定则使用第一个连接字符串-->
<add key="DefaultDb" value="sqlserver" />
<!--字典、权限组件的数据库类型:mysql、npgsql、oracle、sqlite、sqlserver等,默认为sqlserver可不写-->
<add key="ComponentDbType" value="sqlserver" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>

而如果是基于.net core的情况下,读取的是appSettings.json里面的配置信息,配置文件信息如下所示。

{
"ConnectionStrings": {
"Default": "Server=.; Database=WeixinBootstrap2; Trusted_Connection=True;",
"Oracle": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)));User ID=C##ABP;Password=abp",
"MySql": "Server=localhost;Database=myprojectdb;Uid=root;Pwd=123456;",
"PostgreSQL": "Server=localhost;Port=5432;Database=myprojectdb;User Id=postgres;Password=123456"
},
"DbSetting": {
"DefaultDb": "Default",
"ComponentDbType": "sqlserver"
}, ........... }

其中 DefaultDb 指向的是默认的连接字符串配置节点名称,而ComponentDbType为它的数据库类型,如sqlserver,mysql这样的标识。

2、根据不同目标框架读取配置信息

有了上面不同目标框架下的配置信息节点的格式,我们就可以根据目标框架的不同来相应读取配置信息,从而实现不同的初始化处理操作。

        /// <summary>
/// 根据承载环境是netframework或者是.netcore,读取配置信息。
/// 在.netframework中的app.config的appSettings中配置DefaultDb,ComponentDbType,连接字符串在connectionStrings中配置
/// 在.netcore中的appSettings.json的DbSetting节点中配置DefaultDb,ComponentDbType,连接字符串在ConnectionStrings中配置
/// </summary>
/// <returns></returns>
public static DbSetting GetDbSettings()
{
//初始化承载配置信息对象
var dbSetting = new DbSetting(); #if NETFRAMEWORK
//基于.net frameowork下读取app.config的配置
dbSetting.DbType = ConfigurationManager.AppSettings["ComponentDbType"] ?? "sqlserver";
dbSetting.DbConfigName = ConfigurationManager.AppSettings["DefaultDb"]; var setting = ConfigurationManager.ConnectionStrings[1];//默认第一个连接字符串
if (!string.IsNullOrWhiteSpace(dbSetting.DbConfigName))
{
//如果配置节点名称存在,则读取它的连接字符串
setting = ConfigurationManager.ConnectionStrings[dbSetting.DbConfigName];
}
if (setting != null)
{
dbSetting.ConnectionString = setting.ConnectionString;
}
#else
//基于.net core下的读取appsettings.json的配置信息
dbSetting.DbType = GetSectionValue("DbSetting:ComponentDbType") ?? "sqlserver";
dbSetting.DbConfigName = GetSectionValue("DbSetting:DefaultDb"); var connectionStringKey = string.Format("ConnectionStrings:{0}", dbSetting.DbConfigName);
dbSetting.ConnectionString = GetSectionValue(connectionStringKey);
#endif
return dbSetting;
}

我们可以从类的顶部来选择对应的分类,从而实现代码的加亮显示,便于代码的编写。

这样DbContext初始化的时候,就能够顺利适用于不同的目标框架中了,我们在SQLSugar封装的基类就可以不管它的具体处理,只需要初始化DbContext即可,如下代码所示。

基类调用来处理常规的对象返回操作,代码如下所示。

        /// <summary>
/// 获取所有记录
/// </summary>
public virtual async Task<ListResultDto<TEntity>> GetAllAsync()
{
var list = await EntityDb.GetListAsync();
return new ListResultDto<TEntity>()
{
Items = list
};
}

而如果我们需要联合多表来实现联合查询,也可以使用基类的对象进行处理。

如对于字典来说,根据字典大类名称来获取字典项目信息,而字典项目表里面,只有字典大类的ID,那么就需要联合字典大类和字典项目两个表进行关联查询了,如下代码所示。

        /// <summary>
/// 根据字典类型名称获取所有该类型的字典列表集合(Key为名称,Value为值)
/// </summary>
/// <param name="dictTypeName">字典类型名称</param>
/// <returns></returns>
public async Task<Dictionary<string, string>> GetDictByDictType(string dictTypeName)
{
var query = this.dbContent.Client.Queryable<DictDataInfo, DictTypeInfo>(
(d, t) => d.DictType_ID == t.Id && t.Name == dictTypeName)
.Select(d => d); //联合条件获取对象 query = query.OrderBy(d => d.DictType_ID).OrderBy(d => d.Seq);//排序
var list = await query.ToListAsync();//获取列表 var dict = new Dictionary<string, string>();
foreach (var info in list)
{
if (!dict.ContainsKey(info.Name))
{
dict.Add(info.Name, info.Value);
}
}
return dict;
}

这样就可以实现联合表的查询处理。

至此,我们就可以无差别的在不同的目标框架上,根据不同的配置文件来初始化我们的DbContext类,从而无差别的使用基于SqlSugar的数据库访问处理的基类,简化了框架的处理。

基于SqlSugar的数据库访问处理的封装,支持.net FrameWork和.net core的项目调用的更多相关文章

  1. 基于SqlSugar的数据库访问处理的封装,在.net6框架的Web API上开发应用

    我前面几篇随笔介绍了关于几篇关于SqlSugar的基础封装,已经可以直接应用在Winform项目开发上,并且基础接口也通过了单元测试,同时测试通过了一些Winform功能页面:本篇随笔继续深化应用开发 ...

  2. 基于SqlSugar的数据库访问处理的封装,支持多数据库并使之适应于实际业务开发中

    在我的各种开发框架中,数据访问有的基于微软企业库,有的基于EFCore的实体框架,两者各有其应用场景,不过多的去比较.最近在使用SqlSugar的时候,觉得这个数据访问处理的组件确实很灵活,据说性能也 ...

  3. 关于PHP建立数据库访问类的封装以及操作php单例模式连接数据库封装类

    建立数据库访问类的封装 <?php   class DBDA {     public $host = "localhost"; //服务器地址     public $ui ...

  4. Java基于数据源的数据库访问

    ☞ 概述 最早接触的Java访问数据库,是通过jdbc接口.后来工作之后,一般是在服务器(如weblogic)配置数据源,通过JNDI使用数据源:最近需要在程序中动态构造数据源,查了些资料,备录于此. ...

  5. C# 核心语法-反射(反射类型、方法、构造函数、属性,实现可配置可扩展,完成数据库访问类反射封装)

    反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类.结构.委托.接口和枚举等)的成员和成员的信息.有了反射,即可对每一个类型了如指掌.另外我还可以直接创建对象,即使 ...

  6. C#—反射(反射类型、方法、构造函数、属性、实现可配置可扩展、数据库访问类反射封装)

    反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类.结构.委托.接口和枚举等)的成员和成员的信息.有了反射,即可对每一个类型了如指掌.另外我还可以直接创建对象,即使 ...

  7. 基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用

    在实际项目开发中,我们可能会碰到各种各样的项目环境,有些项目需要一个大而全的整体框架来支撑开发,有些中小项目这需要一些简单便捷的系统框架灵活开发.目前大型一点的框架,可以采用ABP或者ABP VNex ...

  8. 基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口

    在基于SqlSugar的开发框架中,我们设计了一些系统服务层的基类,在基类中会有很多涉及到相关的数据处理操作的,如果需要跟踪具体是那个用户进行操作的,那么就需要获得当前用户的身份信息,包括在Web A ...

  9. SOCI、LiteSQL、POCO数据库访问类库对比

    最近在做视频的开发,其中视频的设备接入管理服务器.流媒体管理服务器.中心服务器都涉及到了数据库的操作,同时需要兼容大多数版本的数据库,包括mysql.sqlite.oracle.公司原来使用的是ado ...

随机推荐

  1. ClassLoader如何加载class ?

    jvm里有多个类加载,每个类加载可以负责加载特定位置的类,例如,bootstrap类加载负责加载jre/lib/rt.jar中的类, 我们平时用的jdk中的类都位于rt.jar中.extclasslo ...

  2. 为什么 wait(), notify()和 notifyAll ()必须在同步方法或 者同步块中被调用?

    当一个线程需要调用对象的 wait()方法的时候,这个线程必须拥有该对象的锁,接 着它就会释放这个对象锁并进入等待状态直到其他线程调用这个对象上的 notify() 方法.同样的,当一个线程需要调用对 ...

  3. 为什么要用Spring

    1.方便解耦,简化开发 通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合.有了Spring,用户不必再为单实例模式类.属性文件解析 ...

  4. spring 中有多少种 IOC 容器?

    BeanFactory - BeanFactory 就像一个包含 bean 集合的工厂类.它会在客户端 要求时实例化 bean.ApplicationContext - ApplicationCont ...

  5. mapper.xml文件中标签没有提示的解决

    1.首先我们来看看mapper.xml的头文件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTY ...

  6. 链接克隆的设置和kvm 安装

    1.重新定义udev规则 删除   /etc/udev/rules.d/70-persistent-net.rules  网卡信息 #   >    /etc/udev/rules.d/70-p ...

  7. java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?重写跟重载的区别?

    java中的方法重载发生在同一个类里面两个或者多个方法的方法名相同但是参数不同的情况.与此相对,方法覆盖是说子类重新定义了父类的方法.方法覆盖必须有相同的方法名,参数列表和返回类型. 覆盖者可能不会限 ...

  8. js技术之截取substring(int,int)

    案例:把所有单词以空格为分割并将首字母转为大写 <!DOCTYPE html><html lang="en"><head> <meta c ...

  9. 单例模式应用 | Shared_ptr引用计数管理器

    在我们模拟设计 shared_ptr 智能指针时发现,不同类型的 Shared_ptr 不能使用同一个引用计数管理器,这显然会造成内存上的浪费.因此我们考虑将其设计为单例模式使其所有的 Shared_ ...

  10. 阿里云上安装 Ubuntu + MariaDB

    阿里云上安装 Ubuntu + MariaDB 任务 安装第二个磁盘 设置第二个磁盘为数据盘 安装 MariaDB 配置 MariaDB 的数据文件目录 配置 MariaDB 远程访问 安装第二个磁盘 ...