SQLHelper,N层框架(三层框架升级)与c#加密算法和INI

外聘教师管理系统:C#与SQL Server的数据库设计与部署避坑 在教务管理系统的开发中,数据库设计是决定系统稳定性的基石。无论是C#还是其他语言,表结构的外键关系、索引优化以及参数化查询,都直接影响后续业务逻辑的可靠性与性能。以课时费结算场景为例,若课时记录表缺少组合索引或未正确设置结算状态条件,轻则统计出错,重则财务翻车。本文从数据库设计原理出发,剖析外聘教师管理系统的核心表结构、视图与存储过程,并给出部署时登录名配置、数据库附加等常见问题的解决方案,帮助工程师用SQL Server构建高效、可维护的教务系统,最终自然收敛到外聘教师课时管理的实践落地。 阅读详情

1。什么是SQLHelper?

SqlHelper是基于.NET Framework开发的数据库操作组件,主要通过封装ADO.NET对象(如SqlConnection、SqlCommand)简化数据库访问流程。该组件通过静态方法提供统一的数据访问模式,支持传入连接字符串和SQL参数快速执行数据库交互。


解读SQLHelper:
https://blog.youkuaiyun.com/weixin_66547608/article/details/150936831

原版下载:
https://www.cnblogs.com/dnawo/archive/2012/08/14/2638401.html

中文注释版下载:
https://www.cnblogs.com/gb2013/archive/2009/12/20/1628013.html


2。N层框架?


N层框架核心层:


Model层,模型层,实体层,主要负责对数据库中的对象(表,视图,存储过程等)做映射,把数据库中的对象转化成C#语言中的类对象,将来在C#项目中使用类对象,就相当于使用了数据库中的对象。  映射:ORM  对象关系映射   Object Relation Mapping

IDAL接口层,负责抽象DAL层中的共性。将来不同的数据库都可以实现这个共性,达到一个项目使用多个数据库的目的,可以方便的切换数据库。

DAL数据访问层,主要负责和数据库交互。SQLServerDAL负责和SQLServer数据库交互,OracleDAL负责和Oracle数据库交互。

DALFactory抽象工厂层,主要负责DAL的创建(实例化)。根据各种数据库的DAL都必须实现某种接口IDAL,才可以让抽象工厂层根据配置文件创建不同数据库实现的DAL。有了抽象工厂层,可以让BLL不再强依赖DAL,达到解耦的目的。

BLL业务逻辑层,主要负责对数据库交互(即DAL层)封装,以及对UI校验逻辑的封装。UI层将来直接使用BLL层,UI不使用DAL。

UI层:WindowForm项目来实现UI层,UI层依赖BLL,Model,DAL

以下两层是工具层,不是核心层:
Common层,公共层,一般把一个“小工具”封装到这一层中,供其他层使用。也可以称为“助手层”

DBUtility层,数据库工具层


N层框架依赖关系:


Model不依赖任何层
IDAL依赖Model
SQLServerDAL依赖IDAL,Model,Utility
DALFactory依赖Utility
BLL依赖IDAL,DALFactory,Model
UI依赖BLL,Model,SQLServerDAL


3。回顾一下ADO.NET六大对象?


a. SqlConnection

b. SqlCommand  对象重要的属性:
CommandType
CommandText
Parameters
SqlCommand  重要的方法:
ExecuteNoQuery()
ExecuteReader()
ExecuteScalar()

c. SqlDataReader

d. SqlDataAdapter

e. DataSet

f. SqlParameter

一、连接式操作核心(全程依赖数据库连接)

1. Connection 数据库连接对象

✅ 一句话定位:所有数据库操作的基础,负责建立应用和数据库的物理连接
✅ 核心重点:

  • 核心配置:ConnectionString连接字符串,存储数据库地址、账号、库名、连接超时等信息
  • 关键操作:Open()打开连接、Close()关闭连接
  • 必守规则:连接是稀缺资源,用完必须及时释放,推荐用using语法自动释放(ADO.NET默认启用连接池复用连接,不主动释放会导致资源耗尽)

2. Command SQL 命令执行对象

✅ 一句话定位:向数据库发送 SQL 语句、存储过程的载体
✅ 核心重点:

  • 核心配置:CommandText(要执行的 SQL / 存储过程名)、Parameters(参数集合,用于参数化查询,是防范 SQL 注入的核心手段)
  • 三个执行方法对应完全不同的场景:
    • ExecuteNonQuery():执行增删改操作,返回受影响的行数
    • ExecuteScalar():执行查询,返回结果集第一行第一列的值,适合查COUNT、SUM这类单值结果
    • ExecuteReader():执行查询,返回数据流对象DataReader

3. DataReader 数据读取器

✅ 一句话定位:高性能、低内存占用的只读数据遍历工具
✅ 核心重点:

  • 特点:全程需要保持连接打开,只能按顺序向前遍历、只读不能改,内存开销极小,读取速度极快
  • 适用场景:只需要快速遍历查询结果、不需要修改数据的场景,比如查询大量列表数据
  • 注意:用完必须立即关闭,否则会一直占用连接

4. Transaction 事务对象

✅ 一句话定位:保证多步数据库操作的原子性(要么全部成功,要么全部回滚)
✅ 核心重点:

  • 使用流程:Connection.BeginTransaction()开启事务 → 所有待执行的Command都绑定到该事务 → 所有操作成功调用Commit()提交 → 出现异常调用Rollback()回滚所有操作
  • 适用场景:转账、订单生成这类需要多步操作强一致的场景

二、离线式操作核心(可断开数据库连接操作内存数据)

5. DataAdapter 数据适配器

✅ 一句话定位:连接数据库和离线数据集的「桥梁」
✅ 核心重点:

  • 内置 4 个 Command 对应 4 类操作:SelectCommand(查询)、InsertCommand(新增)、UpdateCommand(修改)、DeleteCommand(删除)
  • 两个核心方法:
    • Fill():自动管理连接生命周期,把数据库数据拉取填充到DataSet/DataTable,不需要手动打开 / 关闭连接
    • Update():把离线数据集里的修改批量同步回数据库
  • 效率技巧:单表操作场景可以搭配CommandBuilder,自动生成增删改 SQL,不需要手动编写

6. DataSet 数据集

✅ 一句话定位:内存中的「微型数据库」,完全离线独立运行
✅ 核心重点:

  • 特点:不需要依赖数据库连接,内部可以存储多张DataTable(数据表),支持定义表间关联、主键、约束,支持对数据做增删改查、过滤、排序,还可以和 XML 互相转换
  • 适用场景:需要离线修改数据、多表关联操作、跨层传输数据的场景
  • 轻量化替代:如果只操作单张表,可直接用更轻量的DataTable

4。SQLHelper助手?


有两个版本:官方,方法少,代码量少
开发者扩展的,带中文注释,重载方法多。虽然多,主要方法就四个重要方法:
a. ExectuteDataset()返回一个DataSet()     FillDataset()没有返回值,但可以填充DataSet参数。
b. ExecuteNoQuery()返回影响的行数
c. ExectuteReader()返回DataReader,循环获取数据
d. ExecuteScalar()返回第一行第一列的值

5。Sql分页方案?


https://blog.youkuaiyun.com/zls365365/article/details/128739389
https://cloud.tencent.com/developer/article/2037986
https://blog.youkuaiyun.com/weixin_37610397/article/details/80892426

推荐两种方案:
sqlserver2012至今 推荐使用offset/fetch next
sqlserver2005至sqlserver2012 之间推荐使用row_number方案

其他方案涉及嵌套查询,性能低,不推荐。

1.分页方案1

--分页方案1:最推荐方案,是目前最好的方案。
select * from College
order by CollegeId 
offset 0 rows fetch next 2 rows only;


--offset偏移量
--偏移量公式:(page-1)*pageSize

declare @page int  -- 页码,第几页
declare @pageSize int --每页显示几条数据

set @page=4
set @pageSize=2

select * from College
order by CollegeId 
offset (@page-1)*@pageSize rows 
fetch next @pageSize rows only;

2.分页方案2

declare @page int
declare @pageSize int
declare @startIndex int;
declare @endIndex int;

set @page=1
set @pageSize=2

/*
	startindex = (page - 1) * pageSize + 1
	endindex = page*pageSize
	page=1, startindex=1, endindex=2
	page=2, startindex=3, endindex=4
	page=3, startindex=5, endindex=6
	page=4, startindex=7, endindex=8

	startIndex = pageSize*page-1
	endindex = pageSize*page
*/

set @startIndex = (@page-1)*@pageSize+1
set @endIndex = @page*@pageSize

;with MyData (RowNum, CollegeId, CollegeName, Status, CreateUserId, CreateTime, LastUpdateUserId, LastUpdateTime)
as
(
	select 
	row_number() over(order by CollegeId asc) as RowNum,* 
	from College
)
select * from MyData 
where RowNum >=@startIndex and RowNum<=@endIndex

3.分页方案2的旧写法

declare @page int
declare @pageSize int
declare @startIndex int;
declare @endIndex int;

set @page=1
set @pageSize=2

/*
	startindex = (page - 1) * pageSize + 1
	endindex = page*pageSize
	page=1, startindex=1, endindex=4
	page=2, startindex=5, endindex=8
	

	startIndex = pageSize*page-1
	endindex = pageSize*page
*/

set @startIndex = (@page - 1) * @pageSize + 1
set @endIndex = @page*@pageSize

select * from 
(
	select 
	row_number() over(order by CollegeId asc) as RowNum,* 
	from College
) as tmp
where RowNum >=@startIndex
and RowNum<=@endIndex

6。C# 加密及解密?

加密算法

根据当前密码学领域的通用分类标准,加密算法主要分为三大类:对称加密算法、非对称加密算法和哈希算法(散列函数)。这三类算法在原理、密钥使用方式和应用场景上有着本质区别,共同构成了现代信息安全的基础。C#中常用的加密算法:DES,AES,RSA,MD5这几种。‌‌

‌

  1. 对称加密算法

对称加密算法,也称为私钥加密算法,其核心特征是加密和解密使用同一把密钥(或可相互推导的等价密钥)。这类算法的优点是加解密速度快、效率高,适合对大量数据进行加密处理。‌‌

‌主要特点‌:算法公开,计算量小,加密效率高。其安全性完全依赖于密钥的保密性,密钥需要在通信双方之间安全共享,这是其主要挑战。‌‌‌

‌常见算法‌:

‌DES (Data Encryption Standard)‌:早期的数据加密标准,使用56位密钥,因密钥过短已被认为不安全,逐渐被淘汰。‌‌‌‌

‌3DES (Triple DES)‌:DES的增强版,对数据块进行三次加密,安全性提高,但处理速度较慢。‌‌‌‌

‌AES (Advanced Encryption Standard)‌:目前最流行、最安全的对称加密标准,用于替代DES。它支持128、192和256位等多种密钥长度,在软硬件上都能快速实现。‌‌

百科

其他算法还包括IDEA、RC系列以及中国的‌SM4‌国家标准算法等。

‌‌

  1. 非对称加密算法

非对称加密算法,也称为公钥加密算法,它使用一对数学上关联的密钥:公钥和私钥。公钥可以公开,用于加密或验证签名;私钥必须保密,用于解密或生成签名。‌非对称加密解决了对称加密中密钥分发难的问题,但加解密速度通常比对称加密慢得多。‌‌‌

‌主要特点‌:无需事先共享密钥,解决了密钥分发问题,常用于数字签名、身份认证和密钥协商。其安全性基于复杂的数学难题(如大整数分解、椭圆曲线离散对数)。‌‌‌‌

‌常见算法‌:

‌RSA‌:最经典和广泛应用的非对称算法,安全性基于大整数质因数分解的难度。可用于加密和数字签名。‌‌

‌ECC (椭圆曲线密码学)‌:相比RSA,在相同安全强度下所需密钥长度更短、处理速度更快、存储空间更小,特别适用于移动设备等资源受限环境。‌‌

‌DSA (数字签名算法)‌:主要用于数字签名,不用于加密。‌‌

中国的‌SM2‌椭圆曲线公钥密码算法也是重要的非对称加密标准。

‌‌

  1. 哈希算法  Hash

哈希算法,又称散列函数或摘要算法,是一种单向加密算法。它将任意长度的输入数据映射为固定长度的输出(哈希值),且过程不可逆。‌哈希算法主要用于验证数据的完整性,确保信息在传输过程中未被篡改。‌‌‌

‌主要特点‌:单向性(不可逆)、抗碰撞性(难以找到两个不同输入产生相同输出)、雪崩效应(输入微小改变导致输出巨大差异)。它不需要密钥(但存在带密钥的变种如HMAC)。‌‌‌

‌主要用途‌:密码存储、数字签名、数据完整性校验。‌‌‌

‌常见算法‌:

‌MD5‌:产生128位哈希值,但已被证实存在碰撞漏洞,不再推荐用于安全目的。‌‌

百科‌

‌SHA系列‌:如SHA-1、SHA-256等。SHA-1也已发现弱点,目前‌SHA-256‌等更安全的版本被广泛推荐使用。‌‌


加密算法主要分为三大类:对称加密算法、非对称加密算法和哈希算法(散列函数)。
C#中常用的加密算法:DES,AES,RSA,MD5这几种。

对称加密算法,也称为私钥加密算法,其核心特征是加密和解密使用同一把密钥。 DES,AES
非对称加密算法,也称为公钥加密算法,它使用一对数学上关联的密钥:公钥和私钥。RAS
哈希算法,又称散列函数或摘要算法,是一种单向加密算法。MD5

https://blog.youkuaiyun.com/weixin_42113456/article/details/151583486
https://www.cnblogs.com/suqq/p/13150546.html
https://blog.51cto.com/u_11566683/6045656?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Utility.Encrypt;

namespace UI
{
    public partial class Form2 : Form
    {
        string key1 = "12345678"; // 必须是8字节
        string key2 = "12345678901234567890123456789012"; // 必须是32字节
        RSA rsa = RSA.Create();
        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // DES加密
            if (radioButton1.Checked)
            {
                textBox2.Text = DESHelper.Encrypt(textBox1.Text, key1);
            }
            // AES加密
            if (radioButton2.Checked)
            {
                textBox2.Text = AESHelper.Encrypt(textBox1.Text, key2);
            }
            // RSA加密
            if (radioButton3.Checked)
            {
                // 产生加密使用的公钥
                string publicKey = rsa.ToXmlString(false); // false 表示仅导出公钥
                textBox2.Text = RSAHelper.Encrypt(textBox1.Text, publicKey);
            }
            // MD5加密
            if (radioButton4.Checked)
            {
                textBox2.Text = MD5Helper.Encrypt(textBox1.Text);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            // DES解密
            if (radioButton1.Checked)
            {
                textBox1.Text = DESHelper.Decrypt(textBox2.Text, key1);
            }
            // AES解密
            if (radioButton2.Checked)
            {
                textBox1.Text = AESHelper.Decrypt(textBox2.Text, key2);
            }
            // RSA解密
            if (radioButton3.Checked)
            {
                // 产生解密使用的私钥
                string privateKey = rsa.ToXmlString(true); // true 表示导出私钥
                textBox1.Text = RSAHelper.Decrypt(textBox2.Text, privateKey);
            }
            // MD5解密
            if (radioButton4.Checked)
            {
                MessageBox.Show("MD5无法解密,只能暴力破解!");
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string mw = MD5Helper.Encrypt(textBox3.Text);
            if (mw == textBox2.Text)
            {
                MessageBox.Show("猜对了!");
            }
            else
            {
                MessageBox.Show("猜错了!");
            }
        }
    }
}

using System;
using System.Security.Cryptography;
using System.Text;

namespace Utility.Encrypt
{
    public static class AESHelper
    {
        private static string iv = "1234567890123456"; // 必须是16字节
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="key">密钥</param>
        /// <returns>密文</returns>
        public static string Encrypt(string plainText, string key)
        {
            // 创建AES对象(也是加密服务提供者)
            using (Aes aes = Aes.Create())
            {
                // 给加密服务提供者设置一些参数
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = Encoding.UTF8.GetBytes(iv);
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.PKCS7;

                // 创建加密者
                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

                byte[] inputBytes = Encoding.UTF8.GetBytes(plainText);
                byte[] encryptedBytes = encryptor.TransformFinalBlock(inputBytes, 0, inputBytes.Length);

                return Convert.ToBase64String(encryptedBytes);
            }
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="cipherText">密文</param>
        /// <param name="key">密钥</param>
        /// <returns>明文</returns>
        public static string Decrypt(string cipherText, string key)
        {
            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = Encoding.UTF8.GetBytes(iv);
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.PKCS7;

                ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

                byte[] cipherBytes = Convert.FromBase64String(cipherText);
                byte[] decryptedBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);

                return Encoding.UTF8.GetString(decryptedBytes);
            }
        }
    }
}
using System;
using System.Security.Cryptography;
using System.Text;

namespace Utility.Encrypt
{
    /// <summary>
    /// DES加密解密
    /// </summary>
    public static class DESHelper
    {
        private static string iv = "abcd6666"; // 初始化向量(8字节,必须是8个字节)
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText">纯文本(明文)</param>
        /// <param name="key">密钥(8字节)</param>
        /// <returns>密文</returns>
        public static string Encrypt(string plainText, string key)
        {
            // DESCryptoServiceProvider类是 DES加密服务的提供者
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                // 给加密服务提供密钥和初始化向量
                des.Key = Encoding.UTF8.GetBytes(key);
                des.IV = Encoding.UTF8.GetBytes(iv);
                // 加密者
                ICryptoTransform encryptor = des.CreateEncryptor(des.Key, des.IV);
                // 先把明文编码,转换UTF8编码的字节数组。
                byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
                // TransformFinalBlock()把明文的字节数组转换成密文的字节数组 。
                byte[] encryptedBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
                // 把密文字节数组转换成Base64字符串
                return Convert.ToBase64String(encryptedBytes);
            }
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="cipherText">密文</param>
        /// <param name="key">密钥(8字节)</param>
        /// <returns>明文</returns>
        public static string Decrypt(string cipherText, string key)
        {
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                des.Key = Encoding.UTF8.GetBytes(key);
                des.IV = Encoding.UTF8.GetBytes(iv);

                ICryptoTransform decryptor = des.CreateDecryptor(des.Key, des.IV);

                byte[] cipherBytes = Convert.FromBase64String(cipherText);
                byte[] decryptedBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);

                return Encoding.UTF8.GetString(decryptedBytes);
            }
        }
    }
}
using System.Security.Cryptography;
using System.Text;

namespace Utility.Encrypt
{
    public static class MD5Helper
    {
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <returns>密码</returns>
        public static string Encrypt(string plainText)
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] inputBytes = Encoding.UTF8.GetBytes(plainText);
                byte[] hashBytes = md5.ComputeHash(inputBytes);
                StringBuilder sb = new StringBuilder();
                foreach (byte b in hashBytes)
                {
                    sb.Append(b.ToString("x2")); // 转换为16进制字符串
                }
                return sb.ToString();
            }
        }
    }
}
using System;
using System.Security.Cryptography;
using System.Text;

namespace Utility.Encrypt
{
    public static class RSAHelper
    {
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="publicKey">公钥</param>
        /// <returns>密文</returns>
        public static string Encrypt(string plainText, string publicKey)
        {
            // 把明文转换成字节数组
            byte[] data = Encoding.UTF8.GetBytes(plainText);
            // 创建RSA对象(加密服务提供者)
            using (RSA rsa = RSA.Create())
            {
                // 从XML中导入密钥
                rsa.FromXmlString(publicKey);
                // 加密,产生密文字节数组
                byte[] encryptedBytes = rsa.Encrypt(data, RSAEncryptionPadding.Pkcs1);
                // 把密文字节数组转换成Base64字符串
                return Convert.ToBase64String(encryptedBytes);
            }
        }

        /// <summary>
        /// 密文解密
        /// </summary>
        /// <param name="cipherText">密文</param>
        /// <param name="privateKey">私钥</param>
        /// <returns>明文</returns>
        public static string Decrypt(string cipherText, string privateKey)
        {
            // 把密文转换字节数组。
            byte[] data = Convert.FromBase64String(cipherText);
            using (RSA rsa = RSA.Create())
            {
                rsa.FromXmlString(privateKey);
                // 解密,产生明文字节数组
                byte[] decryptedBytes = rsa.Decrypt(data, RSAEncryptionPadding.Pkcs1);
                return Encoding.UTF8.GetString(decryptedBytes);
            }
        }
    }
}

7。INI文件读写

INI文件

INI文件(Initialization File)是一种结构简单、人类可读的纯文本配置格式,由节([section])、键值对(key=value)和注释(;或#开头)组成,当前仍广泛用于轻量级、非复杂场景的配置管理。

INI文件详细了解:https://baike.baidu.com/item/INI/9212321‌‌

  1. 应用场景:

‌应用程序本地配置‌:如游戏设置(分辨率、语言)、桌面软件偏好(主题、路径)、工具链参数(端口、超时、日志级别),便于手动修改且无需注册表或复杂解析。

‌嵌入式与资源受限系统‌:因文件体积小、解析开销低,常用于IoT设备、单片机固件(如使用minIni库)存储运行参数,避免使用数据库或JSON/YAML的解析负担。

‌遗留系统维护与兼容性‌:Windows早期系统(win.ini、system.ini)及部分老式企业软件仍依赖INI;Qt、Git(如.gitconfig可设为INI格式)等跨平台工具也支持INI作为可选配置格式。

‌开发/测试环境隔离‌:通过不同INI文件(如dev.ini、prod.ini)管理数据库连接、API地址等,避免代码硬编码,支持快速切换环境。

‌系统级个性化设置‌:Windows中desktop.ini用于自定义文件夹图标/背景;某些安装程序或启动加载器(如旧版Windows的boot.ini)曾用其引导配置(现代系统多被BCD取代)。‌‌

虽已被XML、JSON、YAML等在复杂结构、类型安全、嵌套支持上逐步替代,但‌INI仍因其简洁性、易编辑性、跨平台文本兼容性,在轻量级、静态、非敏感配置场景保持实用价值‌。不适用于密钥存储(明文风险)、动态数据、多层级嵌套或需模式校验的场

  1. 在上位机行业中应用场景:

INI 文件在上位机中主要用于存储轻量级、结构化配置信息,便于人工可读、跨机器部署和快速初始化。‌‌

‌通信参数配置‌:如串口(波特率、数据位、停止位)、TCP/IP(IP、端口)、Modbus地址等,启动时自动加载,避免重复设置。

‌人机界面(HMI)偏好‌:保存窗口位置、主题颜色、字体大小、报警阈值等,实现“上次状态恢复”。

‌多设备/多产线适配‌:通过不同 INI 文件(如 Line1.ini、Line2.ini)切换控制策略,无需重新编译软件。

‌快捷指令或脚本列表‌:保存常用发送命令(如 16 进制指令集),用于调试或自动化测试(如 Python/LabVIEW 上位机)。

‌多语言界面支持‌:节名对应语言(如 [English]、[Chinese]),键值存界面文本,实现简易本地化。

‌调试与现场部署‌:客户可手动编辑 INI 文件调整参数(如校准系数、超时时间),无需数据库或复杂配置工具,契合工业现场“简单可靠”需求。‌‌

虽 XML/JSON/SQLite 更结构化,但 INI 因‌纯文本、无依赖、易编辑、跨平台兼容‌(Windows/Linux 均可解析),仍在工控、测试测量、嵌入式上位机中广泛使用,尤其适合参数不多、无需事务保障、强调可维护性的场景。注意不用于存储敏感信息(如密码)或高频写入数据(易损坏、无锁机制)。‌‌


INI文件(Initialization File)是一种结构简单、人类可读的纯文本配置格式,由节([section])、键值对(key=value)和注释(;或#开头)组成,当前仍广泛用于轻量级、非复杂场景的配置管理。

应用场景:配置通信参数,产线配置,程序配置,系统配置等
https://cloud.tencent.com/developer/article/2416602
https://www.jb51.net/program/334601b8z.htm

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Utility;

namespace UI
{
    public partial class Form3 : Form
    {
        INIFileHelper helper = new INIFileHelper();
        INIFileHelper helper2 = new INIFileHelper("D://a.ini");

        public Form3()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            /* helper.Set("section1", "key1", "value1");
             helper.Set("section2", "name", "张三");*/

            helper2.Set("section1", "key1", "value1");
            helper2.Set("section1", "key2", "value2");
            helper2.Set("section2", "name", "张三");
            helper2.Set("section2", "age", "20");


            MessageBox.Show("写入成功!");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //string result = helper.Get("section2", "name");
            string result = helper2.Get("section2", "name");
            MessageBox.Show(result);

        }
    }
}

using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Utility
{
    public class INIFileHelper
    {
        private string path = Environment.CurrentDirectory + "\\" + "config.ini";

        public INIFileHelper() { }

        public INIFileHelper(string path)
        {
            this.path = path;
        }

        // C#中如何调用其他语言编写动态链接库?

        // kernel32就是windows系统自带的一个动态链接库,它提供了一系列的API,用来操作ini文件。但不是C#编写的源。 将来操作系统中有很其他语言(C或C++)编写的动态链接库,如user32.dll。动态链接库(Dynamic Link Library)。kernel32.dll在操作系统的C:\Windows\System32目录下。

        // DllImport特性专门用来导入动态链接库的API
        // 把某个动态链接库中的API导入到C#程序中时,有些导入细节:
        // 1。必须是静态的static, 且外部的extern(不是用C#语言编写的)
        // 2。导入动态链接库时,DllImport("动态链接库的名称"),其他的参数都是可选的
        [DllImport("kernel32.dll")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

        /// <summary>
		/// 写INI文件
		/// </summary>
		/// <param name="section">写入的节点</param>
		/// <param name="key">键</param>
		/// <param name="val">值</param>
		public void Set(string section, string key, string val)
        {
            WritePrivateProfileString(section, key, val, this.path);
        }

        /// <summary>
        /// 读取INI文件
        /// </summary>
        /// <param name="section">读取的节点</param>
        /// <param name="key">键</param>
        /// <returns>值</returns>
        public string Get(string section, string key)
        {
            StringBuilder temp = new StringBuilder(255);
            GetPrivateProfileString(section, key, "", temp, 255, this.path);
            return temp.ToString();
        }
    }
}

简化.NET数据库操作的SqlHelper类库 本文还有配套的精品资源,点击获取 简介:SqlHelper是一个.NET类库,用于简化数据库操作,提高代码的可读性和可维护性。通过提供静态方法执行SQL命令,支持参数化查询以提高安全性,支持事务处理,并为不同数据库系统(如Oracle、SQL Server、Access)提供特定实现。此外,SqlHelper支持通过配置文件读取连接信息,并设计成易于扩展的模块化结构,使得开... 阅读详情

相关推荐

构建高效自定义SQLHelper数据库操作类

本文还有配套的精品资源,点击获取 简介:本文深入探讨了一个自定义的SQLHelper类——"自己的SQLHelper",它是一个封装了基础SQL查询和数据库交互的工具,旨在提升开发效率。这个工具在.NET开发环境中常见,基于***构建,具备连接管理、参数化查询、事务支持、数据转换、扩展性、错误处理和批量操作等特性。文章还提供了对SQLHelper代码结构的分析,以及如何利用...

weixin_31715353的博客 1731

sqlhelper 的使用 (C#)超级详细的入门教程

sqlhelper 的使用 (C#)超级详细的入门教程

RJGCWJH的博客 1万+

.NET数据访问简化工具:SqlHelper类

在.NET开发中,处理数据库操作是一项常见而重要的任务。但直接编写数据库操作的代码可能会导致项目中出现大量的重复代码,降低了开发效率,增加了代码维护的难度。此外,直接编写数据库操作代码也容易导致SQL注入等安全问题。这时,SqlHelper类库的作用就显得尤为重要了。SqlHelper类库是专门为.NET环境下数据库操作而设计的一个辅助类库,它可以简化数据库操作代码,提高开发效率,并且增强程序的安全性。

weixin_33750664的博客 1195

SqlHelper方法

1.SqlHelper介绍 是一个sql的辅助类,可以是代码更简洁,更有可读性! 2. 类方法方法介绍 retBool(Integerresult):判断数据库操作是否成功 getObject(List<E>list):从list中取第一条数据返回对应List中泛型的单个结果 fillWrapper(Page<?>page, Wrapper<?>wrapper):填充Wrapper sqlSession(Class<?>clazz):获取...

weixin_43522117的博客 4946

深入理解SqlHelper:源码解析与使用实例

SqlHelper类库是.NET环境下简化数据库操作的一个实用工具库,它提供了一套方法封装,使得开发者在进行数据库交互时,能够以更少的代码量和更高的效率完成任务。这个类库遵循最少惊喜原则,旨在通过抽象化数据库操作,减少重复代码,提高开发的生产力。ExecuteNonQuery方法主要用于执行不返回任何结果集的SQL语句,比如INSERT、UPDATE和DELETE操作。这些操作会修改数据库中的数据,但不会返回新的数据。在处理批量数据操作和数据迁移时,这个方法非常有用。

weixin_42393362的博客 940

C#数据库操作简化器:SqlHelper类详解

本文还有配套的精品资源,点击获取 简介: SqlHelper.cs 是一个C#类文件,用于简化数据库连接和操作,封装了***的常用功能。它提供了创建和执行SQL命令、参数化查询、事务处理、错误处理以及连接池等核心功能。通过使用 SqlHelper 类,开发者可以避免直接处理繁琐的数据库操作细节,同时保证操作的安全性和效率。本文将详细解读 ...

weixin_42599908的博客 1440

C# SqlHelper 详解(自己总结)

序言 数据库是我们常用的存储数据的容器,网上有很多关于SqlHelper 类库,里面有的写的很复杂很详细(有点冗余),有很多方法基本上用不到,所以自己根据很多的项目实践总结了一套适合自己的SqlHelper 类 包括 数据库的增、删、改、查、存储过程、事务等,以便后续使用,希望能给诸君有些帮助,如有错误麻烦请指出并纠正。 数据库的创建 创建一个银行信息数据 use master --- 判断 系统是否有数据库 if exists(select * from sys.databases where

qq_39138424的博客 3062

Duilib的简单使用(五、DuiDesigner/DuiEditor的下载编译)

一、前言 在Duilib的简单使用(一、duilib demo)中我们介绍了利用duilib简单的构造一个项目 在Duilib的简单使用(二、xml实现界面与业务分离)中我们介绍了XML在duilib中的使用 在Duilib的简单使用(三、界面逻辑交互)中我们已经知道如何简单的进行界面的交互 在Duilib的简单使用(四、换肤)中,我们提了一下Duilib强大的一键换肤功能。 通过之前的说明,我们知道duilib是通过xml来分离界面和业务逻辑的,但是xml如果不能预览,那每次敲一个再运行一下看看效果,这不

LyRics1996的博客 2884

c#中可以使用的sqlhelper类

c#中dbhelper

ALI_SAf的博客 1187

深度学习 tesorflow2.0版本 入门第一章

为什么要学tensflow 深度学习发展迅猛 框架灵活 google开发 公司应用广泛 2.0更加灵活 后面会学习的项目 图像分类 房价预测 泰坦尼克号生存预测 文本分类 文本生成 机器翻译 核心部分 模型训练 tesorboard----> 查看模型训练进度 模型保存和部署 分布式训练-----> 加速训练速度,提升训练效率 TensorFlow常用库:Tfds, tfhub,tensor2tensor 多平台云端环境GPU:Goolgle cloud环境配置,AWS环境配置 kaggle平

weixin_46969441的博客 1234

MIMIC数据库基本信息分析

一、MIMIC数据库中26张表介绍 数据库中一共有26张表,记录患者入院的各种信息,每张表的介绍如下所示。 表格名 信息 admission 患者基本信息,比如性别、种族、语言、宗教、婚姻、入院和出院时间、死亡时间等 callout 提供病人准备从ICU转出或者已经从ICU转出时相关信息 caregivers 记录医护人员信息(ID、类型、附加...

m0_37520426的博客 1万+

微软官方SqlHelper类 数据库辅助操作类

Web.config配置。

qq165285727的专栏 397

Sigrity SystemSI仿真分析教程文件路径

为了方便读者能够快速上手和学会Sigrity SystemSI 的功能,将Sigrity SystemSI仿真分析教程专栏所有文章对应的实例文件上传至以下路径。

weixin_54787054的博客 707

c#读取到web.config里的数据库连接字符串

看了N多.NET三层的资料,可是自己还没有真的试过用三层来做个小项目,今天终于下决心,用三层做个新闻发布系统,很简单,对数据库的增删查改而已。。。 没想到在刚刚开始的时候就碰到了麻烦,在解决方案里添加新建项目DAL后如何在DAL中的类中读取到web.config里的数据库连接字符串。。。。 经本人多方查证和搜索,终于解决,现在方法记下: 新建项目 文件→添加→新建项目 选择C#的内

ppdtts520的专栏 7192

撸毛笔记-朴朴超市 v1.01

朴朴超市 v1.01脚本地址:自动签到和组队赚朴分, 朴分可以抵扣50%的金额组队瓜分需要4人成团, 每个号每天只能开团和入队各一次每天跑一两次即可使用扫码或自己想办法捉refreshToken扫码获取token: (先微信进入朴朴超市小程序并登录注册过账号再扫码)把获取的refreshToken和备注(非必须)填到文件pupuCookie.txt里(第一次运行会自动创建), 多账号换行或&或@隔开。

xiaoshun007的专栏 1804

风机叶片小规模振动监测数据集--读取测试

ETH风电叶片缺陷数据集–读取测试 数据简介 提示:这里可以添加本文要记录的大概内容: 结构健康监测是保障重要机电设备、建筑设施健康的重要技术手段。 一、lvm_read包安装 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务

cnjs1994的博客 2850

学习笔记:SqlHelper(SQL SERVER)

一、思维导图 二、知识点描述   SqlHelper用于简化重复的去写那些数据库连接(SqlConnection),SqlCommand,SqlDataReader等等的代码。SqlHelper 封装过后通常是只需要给方法传入一些参数如数据库连接字符串,SQL参数等,就可以访问数据库。SqlHelper 类用于通过一组静态方法来封装数据访问功能。该类不能被继承或实例化,因此将其声明为包含专...

Q_0048的博客 1036

【嵌入式DIY实例-Arduino篇】-脉搏传感器监测脉搏率 (BPM)及可视化

在本文中,我们将使用 Arduino 和脉搏传感器来测量心率 (BPM)。 在文章中,我们将向展示如何使用脉搏传感器测量您的心率(每分钟心跳次数),并在电脑上位机通过Processing来实现心率数据可视化。同时使用LCD16×2 显示屏显示脉搏率 BPM。 该传感器易于使用和操作。 只需将手指放在传感器顶部,它就会测量心跳变化。

视觉与物联智能 834

c#中SqlHelper类的使用

这样就实现了对数据库的CRUD操作的封装。

weixin_45778846的博客 1183

瑞芯微RV1126部署YOLOv8全流程:环境搭建、pt-onnx-rknn模型转换、C++推理代码、错误解决、优化、交叉编译第三方库

瑞芯微RV1126部署YOLOv8全流程:环境搭建、pt-onnx-rknn模型转换、C++推理代码、错误解决、优化、交叉编译第三方库

C/C++、嵌入式开发、深度学习算法、模型部署与推理优化 3103

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

常用SqlHelper类(C#)

SqlHelper类 public static class SqlHelper { //连接字符串 private static readonly string connStr = ConfigurationManager.ConnectionStrings["mssql"].ConnectionString; //1.执行增、删、...

Hugh的博客 2万+

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

SqlHelper中的ExcuteNonQuery方法

SqlHelper中的ExcuteNonQuery方法。

Asyouwishing1的博客 505

Mybatis工具SqlHelper - 获取Mybatis方法的Sql

如果你想在代码中获取执行的sql

偶尔记一下 - mybatis.io 3万+

SqlHelper类的方法详细解读和使用示例

本文详细介绍了C#中SqlHelper类的实现与应用,包括核心方法对比、完整代码实现及多种使用场景示例。SqlHelper封装了ADO.NET操作,提供ExecuteNonQuery(增删改)、ExecuteScalar(聚合查询)、ExecuteReader(大数据流读取)和ExecuteDataTable(UI数据绑定)等方法。文章通过CRUD操作、事务处理等实际案例,并强调参数化查询防注入、连接管理、异常处理等最佳实践,帮助开发者提升数据库操作效率与安全性。

weixin_66547608的博客 1258

C#中SqlHelper工具类的实现

/存储过程 or Sql语句。/// 第一行第一列。

一支黑色の铅笔博客 757

C#数据库教程4-ADO.NET自己封装SqlHelper类

目录 一、版本1.0 1、方法封装 (1)ExecuteNonQuery方法 (2)ExecuteScalar方法 (3)ExecuteDataTable方法 2、调用测试 界面 (1)插入数据 (2)查询数据 (3)DataTable查询 二、版本2.0 1、方法封装 (1)ExecuteNonQuery方法 (2)ExecuteScalar方法 (3)ExecuteDataTable方法 2、调用测试 界面 (1)插入数据 (2)查询数据 (3)DataTabl.

panjinliang066333的博客 3753
上一篇: 数据库语句
下一篇: 数据库语句 触发器 作业
柔蘭
博客等级 码龄3年 34粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值