C#连接SQL Server数据库完整指南_c#连接sqlserver数据库
目录
一、环境准备
1. 安装必要软件
2. 创建测试数据库
二、方式1:ADO.NET原生连接封装类
步骤1:添加引用
步骤2:编写连接字符串
1. 封装类
2. 使用示例
三、方式2:Entity Framework Core封装类
步骤1:安装NuGet包
步骤2:创建实体类和DbContext
步骤3:执行CRUD操作
1. 封装类
2. 使用示例
四、最佳实践与扩展功能说明
1. 连接字符串管理
2. 异常处理
3. 日志记录
4. 性能优化
5. 扩展功能
五、总结
C#连接SQL Server数据库完整指南,整合了ADO.NET原生连接与Entity Framework Core两种实现方式,包含详细的代码注释和实现过程说明。
一、环境准备
1. 安装必要软件
- Visual Studio(社区版免费):下载地址
- SQL Server(Developer Edition免费):下载地址
- SQL Server Management Studio (SSMS):下载地址
2. 创建测试数据库
-- 创建数据库,数据库名TestDBCREATE DATABASE TestDB;GOUSE TestDB;GO -- 创建用户表CREATE TABLE Users ( UserID INT PRIMARY KEY IDENTITY(1,1), Username NVARCHAR(50) NOT NULL, Email NVARCHAR(100) UNIQUE);GO -- 插入测试数据INSERT INTO Users (Username, Email) VALUES (\'Alice\', \'alice@example.com\'), (\'Bob\', \'bob@example.com\');GO
二、方式1:ADO.NET原生连接封装类
步骤1:添加引用
- 在Visual Studio中右键项目 → 管理NuGet程序包 → 搜索并安装:
Install-Package System.Data.SqlClient
步骤2:编写连接字符串
- 在
app.config
或web.config
中添加:
- 连接字符串参数说明:
Server=.
:本地默认实例(.\\SQLEXPRESS
表示命名实例)。Database=TestDB
:目标数据库名。Integrated Security=True
:使用Windows身份验证(若用SQL账号,改为User ID=sa;Password=你的密码
)。
1. 封装类
csharp
using System.Data;using System.Data.SqlClient;using Microsoft.Extensions.Configuration; // 插入数据(参数化查询防SQL注入) /* using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); string insertQuery = \"INSERT INTO Users (Username, Email) VALUES (@name, @email)\"; using (SqlCommand cmd = new SqlCommand(insertQuery, conn)) { cmd.Parameters.AddWithValue(\"@name\", \"Charlie\"); cmd.Parameters.AddWithValue(\"@email\", \"charlie@example.com\"); cmd.ExecuteNonQuery(); } }*////
/// ADO.NET数据库操作封装类/// public class AdoNetDbHelper{ private readonly string _connectionString; ////// 构造函数:从配置文件读取连接字符串 /// /// 配置对象 /// 连接字符串名称(默认TestDB) public AdoNetDbHelper(IConfiguration config, string connectionStringName = \"TestDB\") { _connectionString = config.GetConnectionString(connectionStringName) ?? throw new InvalidOperationException(\"未找到指定连接字符串\"); } ////// 执行查询操作,返回DataTable /// /// SQL语句 /// 命令类型(默认Text) /// SQL参数 /// 查询结果DataTable public DataTable ExecuteQuery(string sql, CommandType commandType = CommandType.Text, SqlParameter[] parameters = null) { // 使用using语句确保资源释放 using (SqlConnection conn = new SqlConnection(_connectionString)) { using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.CommandType = commandType; // 添加参数(防SQL注入) if (parameters != null) { cmd.Parameters.AddRange(parameters); } // 填充数据到DataTable SqlDataAdapter adapter = new SqlDataAdapter(cmd); DataTable dt = new DataTable(); adapter.Fill(dt); return dt; } } } ////// 执行非查询操作(INSERT/UPDATE/DELETE),返回受影响行数 /// /// SQL语句 /// 命令类型(默认Text) /// SQL参数 /// 受影响行数 public int ExecuteNonQuery(string sql, CommandType commandType = CommandType.Text, SqlParameter[] parameters = null) { using (SqlConnection conn = new SqlConnection(_connectionString)) { using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.CommandType = commandType; if (parameters != null) { cmd.Parameters.AddRange(parameters); } conn.Open(); // 显式打开连接 return cmd.ExecuteNonQuery(); } } } ////// 执行事务处理(含重试逻辑) /// /// 事务操作委托 /// 最大重试次数(默认3次) /// 重试间隔(毫秒,默认1000) /// 成功返回1,失败抛出异常 public int ExecuteTransaction(Action action, int maxRetries = 3, int retryDelayMs = 1000) { int retryCount = 0; while (retryCount <= maxRetries) { try { using (SqlConnection conn = new SqlConnection(_connectionString)) { conn.Open(); using (SqlTransaction transaction = conn.BeginTransaction()) { try { // 执行事务操作 action(conn, transaction); // 提交事务 transaction.Commit(); return 1; // 返回成功标识 } catch { // 回滚事务 transaction.Rollback(); throw; // 重新抛出异常 } } } } catch (SqlException ex) when (retryCount < maxRetries) { // 记录重试日志(实际项目需集成日志框架) Console.WriteLine($\"事务执行失败,重试次数: {retryCount + 1}/{maxRetries}\"); retryCount++; Thread.Sleep(retryDelayMs); } } throw new DbOperationException(\"达到最大重试次数,事务执行失败\"); }} ////// 自定义数据库操作异常/// public class DbOperationException : Exception{ public DbOperationException(string message, Exception innerException) : base(message, innerException) { }}
2. 使用示例
csharp
// 配置读取(appsettings.json){ \"ConnectionStrings\": { \"TestDB\": \"Server=.;Database=TestDB;Integrated Security=True;\" }} // 程序入口(Program.cs)var builder = new ConfigurationBuilder().AddJsonFile(\"appsettings.json\");IConfiguration config = builder.Build(); // 创建数据库操作助手实例var dbHelper = new AdoNetDbHelper(config); // 示例1:查询所有用户DataTable usersTable = dbHelper.ExecuteQuery(\"SELECT * FROM Users\");foreach (DataRow row in usersTable.Rows){ Console.WriteLine($\"ID: {row[\"UserID\"]}, 用户名: {row[\"Username\"]}, 邮箱: {row[\"Email\"]}\");} // 示例2:插入新用户(参数化查询防注入)string insertSql = \"INSERT INTO Users (Username, Email) VALUES (@name, @email)\";SqlParameter[] insertParams = { new SqlParameter(\"@name\", \"Eve\"), new SqlParameter(\"@email\", \"eve@example.com\")};dbHelper.ExecuteNonQuery(insertSql, parameters: insertParams); // 示例3:事务处理(转账场景)string updateSql1 = \"UPDATE Accounts SET Balance = Balance - 100 WHERE UserID = 1\";string updateSql2 = \"UPDATE Accounts SET Balance = Balance + 100 WHERE UserID = 2\"; try{ dbHelper.ExecuteTransaction((conn, trans) => { // 在事务中执行多个操作 using (SqlCommand cmd1 = new SqlCommand(updateSql1, conn, trans)) { cmd1.ExecuteNonQuery(); } using (SqlCommand cmd2 = new SqlCommand(updateSql2, conn, trans)) { cmd2.ExecuteNonQuery(); } // 模拟业务逻辑异常(用于测试事务回滚) // throw new InvalidOperationException(\"模拟业务异常\"); }); Console.WriteLine(\"事务执行成功!\");}catch (DbOperationException ex){ Console.WriteLine($\"事务执行失败: {ex.Message}\");}
三、方式2:Entity Framework Core封装类
步骤1:安装NuGet包
- 在项目中安装以下包:
bash
Install-Package Microsoft.EntityFrameworkCore.SqlServerInstall-Package Microsoft.EntityFrameworkCore.Tools
步骤2:创建实体类和DbContext
csharp
using Microsoft.EntityFrameworkCore; // 实体类public class User{ public int UserID { get; set; } public string Username { get; set; } public string Email { get; set; }} // DbContextpublic class AppDbContext : DbContext{ public DbSet Users { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseSqlServer(\"Server=.;Database=TestDB;Integrated Security=True;\");}
步骤3:执行CRUD操作
csharp
class Program{ static void Main() { // 查询数据 using (var db = new AppDbContext()) { var users = db.Users.ToList(); foreach (var user in users) { Console.WriteLine($\"ID: {user.UserID}, Name: {user.Username}\"); } } // 插入数据 using (var db = new AppDbContext()) { var newUser = new User { Username = \"David\", Email = \"david@example.com\" }; db.Users.Add(newUser); db.SaveChanges(); } // 更新数据 using (var db = new AppDbContext()) { var user = db.Users.FirstOrDefault(u => u.Username == \"Alice\"); if (user != null) { user.Email = \"alice_new@example.com\"; db.SaveChanges(); } } // 删除数据 using (var db = new AppDbContext()) { var user = db.Users.FirstOrDefault(u => u.Username == \"Bob\"); if (user != null) { db.Users.Remove(user); db.SaveChanges(); } } }}
注意:
-
连接字符串安全:
-
避免在代码中硬编码密码,使用
app.config
或环境变量存储敏感信息。 -
生产环境建议使用加密连接字符串(如
aspnet_regiis
工具)。
-
-
资源释放:
-
始终使用
using
语句确保SqlConnection
、SqlCommand
等对象被正确释放。
-
-
异常处理:
csharp
try{ // 数据库操作代码}catch (SqlException ex){ Console.WriteLine($\"SQL错误: {ex.Message}\");}catch (Exception ex){ Console.WriteLine($\"通用错误: {ex.Message}\");}
1. 封装类
csharp
using Microsoft.EntityFrameworkCore;using System.Collections.Generic;using System.Threading.Tasks;using Microsoft.Extensions.Logging; ///
/// Entity Framework Core数据库操作封装类/// /// DbContext类型public class EfCoreDbHelper where TContext : DbContext{ private readonly TContext _context; private readonly ILogger<EfCoreDbHelper> _logger; ////// 构造函数 /// /// DbContext实例 /// 日志记录器 public EfCoreDbHelper(TContext context, ILogger<EfCoreDbHelper> logger) { _context = context ?? throw new ArgumentNullException(nameof(context)); _logger = logger; } ////// 获取所有实体数据 /// /// 实体类型 /// 实体集合 public List GetAll() where T : class { _logger.LogInformation(\"正在执行GetAll操作\", typeof(T).Name); return _context.Set().ToList(); } ////// 根据条件查找单个实体 /// /// 实体类型 /// 查询条件 /// 匹配的实体或null public T Find(Func predicate) where T : class { _logger.LogInformation(\"正在执行Find操作\", typeof(T).Name); return _context.Set().FirstOrDefault(predicate); } ////// 添加新实体 /// /// 实体类型 /// 要添加的实体 public void Add(T entity) where T : class { _logger.LogInformation(\"正在执行Add操作\", typeof(T).Name); _context.Set().Add(entity); _context.SaveChanges(); } ////// 更新实体 /// /// 实体类型 /// 要更新的实体(需处于已跟踪状态) public void Update(T entity) where T : class { _logger.LogInformation(\"正在执行Update操作\", typeof(T).Name); _context.Entry(entity).State = EntityState.Modified; _context.SaveChanges(); } ////// 删除实体 /// /// 实体类型 /// 要删除的实体 public void Delete(T entity) where T : class { _logger.LogInformation(\"正在执行Delete操作\", typeof(T).Name); _context.Set().Remove(entity); _context.SaveChanges(); } ////// 执行原始SQL查询 /// /// 映射实体类型 /// SQL语句 /// SQL参数 /// 查询结果集合 public List FromSqlRaw(string sql, params object[] parameters) where T : class { _logger.LogInformation(\"执行原始SQL: {Sql},参数: {Params}\", sql, parameters); return _context.Set().FromSqlRaw(sql, parameters).ToList(); } ////// 异步获取所有实体数据 /// /// 实体类型 /// Task<List> public async Task<List> GetAllAsync() where T : class { _logger.LogInformation(\"正在执行异步GetAll操作\", typeof(T).Name); return await _context.Set().ToListAsync(); }} ////// 用户实体类(对应数据库表)/// public class User{ public int UserID { get; set; } public string Username { get; set; } public string Email { get; set; }} ////// 应用程序DbContext(数据库上下文)/// public class AppDbContext : DbContext{ ////// 用户表数据集 /// public DbSet Users { get; set; } ////// 构造函数 /// /// DbContext配置选项 public AppDbContext(DbContextOptions options) : base(options) { } ////// 配置模型构建(可选,用于高级配置) /// protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置表映射(示例) modelBuilder.Entity() .ToTable(\"Users\") .HasKey(u => u.UserID); }}
2. 使用示例
csharp
// 程序入口(Program.cs)var builder = WebApplication.CreateBuilder(args); // 配置数据库连接(从appsettings.json)builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString(\"TestDB\"))); // 注册EF Core助手类(依赖注入)builder.Services.AddScoped<EfCoreDbHelper>(); // 配置日志记录(控制台输出)builder.Services.AddLogging(configure => configure.AddConsole().SetMinimumLevel(LogLevel.Information)); var app = builder.Build(); // 获取数据库操作助手实例var efHelper = app.Services.GetRequiredService<EfCoreDbHelper>(); // 示例1:查询所有用户var users = efHelper.GetAll();foreach (var user in users){ Console.WriteLine($\"ID: {user.UserID}, 用户名: {user.Username}, 邮箱: {user.Email}\");} // 示例2:添加新用户var newUser = new User { Username = \"Frank\", Email = \"frank@example.com\" };efHelper.Add(newUser); // 示例3:更新用户邮箱var userToUpdate = efHelper.Find(u => u.Username == \"Eve\");if (userToUpdate != null){ userToUpdate.Email = \"eve_new@example.com\"; efHelper.Update(userToUpdate);} // 示例4:执行原始SQL查询var rawQueryUsers = efHelper.FromSqlRaw(\"SELECT * FROM Users WHERE UserID > @id\", 2);foreach (var user in rawQueryUsers){ Console.WriteLine($\"ID: {user.UserID}, 用户名: {user.Username}\");} // 示例5:异步查询(需async/await)app.MapGet(\"/users\", async () =>{ var asyncUsers = await efHelper.GetAllAsync(); return Results.Ok(asyncUsers);}); app.Run();
四、最佳实践与扩展功能说明
1. 连接字符串管理
- 配置文件:
- 使用
appsettings.json
统一管理连接字符串,支持多环境配置(开发/测试/生产)。
- 使用
-
参数化查询:
- 始终使用
cmd.Parameters.AddWithValue()
防止SQL注入攻击。
- 始终使用
- 加密敏感信息:
- 生产环境建议使用Azure Key Vault或类似服务加密存储密码等敏感信息。
2. 异常处理
- 自定义异常:
- 通过
DbOperationException
封装数据库操作异常,包含更详细的错误上下文。
- 通过
- 全局异常处理:
- 在ASP.NET Core中配置全局异常处理中间件,统一记录和处理数据库异常。
3. 日志记录
- 集成日志框架:使用Serilog、NLog等日志框架记录SQL语句、执行时间、错误详情。
- 日志级别控制:开发环境记录详细日志,生产环境仅记录关键错误。
4. 性能优化
- 连接池:ADO.NET默认启用连接池,无需额外配置即可提升性能。
- 查询优化:使用EF Core的
ToQueryString()
方法查看生成的SQL,分析执行计划。 - 异步操作:优先使用异步方法(如
GetAllAsync
)避免线程阻塞。
5. 扩展功能
- 缓存支持:集成MemoryCache或Redis减少数据库压力,对频繁访问且不常变化的数据进行缓存。
- 审计日志:通过数据库触发器或EF Core的
SaveChanges
拦截器记录数据变更历史。 - 多数据库支持:定义
IDbHelper
接口,通过依赖注入实现不同数据库(MySQL、PostgreSQL)的切换。
五、总结
根据项目需求选择合适的技术栈:
- ADO.NET:适合需要精细控制SQL、追求极致性能的场景。
- EF Core:适合快速开发、需要对象关系映射的场景。
通过封装类统一管理数据库操作,结合依赖注入和日志记录等最佳实践,可显著提升代码的可维护性和健壮性。