C#与SQL Server
C#和SQL Server是微软技术栈中非常经典的一对组合C#作为编程语言负责应用程序的逻辑SQL Server作为数据库负责数据的存储和管理。核心交互方式C#程序与SQL Server通信主要通过ADO.NET或基于它的各种ORM框架。1、ADO.NET(原生方式)使用System.Data.SqlCkient命名空间下的类现代.NET使用Microsoft.Data.SqlClient。using Microsoft.Data.SqlClient;string connectionString Serverlocalhost;DatabaseMyDB;User Idsa;PasswordYourPassword;TrustServerCertificateTrue;;// 查询数据using (var conn new SqlConnection(connectionString)){string sql SELECT Id, Name FROM Users WHERE Age Age;var cmd new SqlCommand(sql, conn);cmd.Parameters.AddWithValue(Age, 18);conn.Open();using (var reader cmd.ExecuteReader()){while (reader.Read()){int id reader.GetInt32(0);string name reader.GetString(1);Console.WriteLine(${id}: {name});}}}// 执行增删改using (var conn new SqlConnection(connectionString)){string sql INSERT INTO Users (Name, Age) VALUES (Name, Age);var cmd new SqlCommand(sql, conn);cmd.Parameters.AddWithValue(Name, 张三);cmd.Parameters.AddWithValue(Age, 25);conn.Open();int rowsAffected cmd.ExecuteNonQuery();}关键点始终使用参数化查询防止SQL注入上面的Age、Name。用using语句确保连接和命令对象被正确释放。使用Microsoft.Data.SqlClient微软官方新库替代老的System.Data.SqlClient。2. ORM 框架更高效开发Entity Framework CoreEF Core—— 官方首选将数据库表映射为 C# 类用 LINQ 查询。// 定义实体public class User{public int Id { get; set; }public string Name { get; set; }public int Age { get; set; }}// DbContextpublic class AppDbContext : DbContext{public DbSetUser Users { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder options) options.UseSqlServer(Server...);}// 使用 LINQ 查询using var context new AppDbContext();var adults context.Users.Where(u u.Age 18).ToList();// 插入context.Users.Add(new User { Name 李四, Age 30 });context.SaveChanges();优点不用写 SQL自动处理连接、事务、变更跟踪。适用大多数业务应用特别是 CRUD 为主的项目。Dapper轻量级 ORM接近原生 ADO.NET 性能同时简化了对象映射。using Dapper;using (var conn new SqlConnection(connectionString)){var users conn.QueryUser(SELECT * FROM Users WHERE Age Age, new { Age 18 });conn.Execute(INSERT INTO Users (Name, Age) VALUES (Name, Age), new { Name 王五, Age 22 });}适合对性能要求极高或需要写复杂 SQL 的场景。连接与配置连接字符串常见写法// Windows 身份验证ServermyServerAddress;DatabasemyDataBase;Trusted_ConnectionTrue;TrustServerCertificateTrue;// SQL Server 身份验证ServermyServerAddress;DatabasemyDataBase;User IdmyUsername;PasswordmyPassword;TrustServerCertificateTrue;// 使用实例名Serverlocalhost\\SQLEXPRESS;Database...;最佳实践不要把连接字符串硬编码在代码中应放在appsettings.json.NET Core/6/8/9或 Web.config.NET Framework并加密生产环境的敏感信息。appsettings.json 示例json{ ConnectionStrings: { DefaultConnection: Server.;DatabaseMyDb;Trusted_ConnectionTrue;TrustServerCertificateTrue; } }读取方式csharpvar connectionString builder.Configuration.GetConnectionString(DefaultConnection);常见操作进阶1. 存储过程调用csharpusing (var cmd new SqlCommand(usp_GetUsersByAge, conn)) { cmd.CommandType CommandType.StoredProcedure; cmd.Parameters.AddWithValue(Age, 18); // ... }2. 事务处理csharpusing (var conn new SqlConnection(connectionString)) { conn.Open(); using (var transaction conn.BeginTransaction()) { try { // 执行多个数据库操作都使用同一个 transaction 对象 transaction.Commit(); } catch { transaction.Rollback(); throw; } } }EF Core 中则可以更简单地用context.Database.BeginTransactionAsync()。3. 异步操作推荐csharpusing (var conn new SqlConnection(connectionString)) { await conn.OpenAsync(); var cmd new SqlCommand(sql, conn); using (var reader await cmd.ExecuteReaderAsync()) { while (await reader.ReadAsync()) { // ... } } }性能与安全最佳实践始终使用参数化查询防 SQL 注入。尽早打开连接尽快关闭或用using自动释放。选择合适的数据读取方式ExecuteReader→ 只读、只进流性能最好。ExecuteScalar→ 返回单值如SELECT COUNT(*)。ExecuteNonQuery→ 增删改。**避免 SELECT *** 只取需要的列。大量数据操作时考虑批量操作使用SqlBulkCopy或 EF Core 的AddRange/ExecuteUpdateEF Core 7。连接池ADO.NET 默认启用连接池不用特别处理但务必关闭连接。敏感信息生产环境连接字符串用 Azure Key Vault、环境变量或配置加密。常见错误与排查超时错误增加CommandTimeout优化 SQL 或索引。连接泄漏确保所有SqlConnection都 Dispose 了用using。已关闭的连接操作前检查conn.State需要时Open。找不到 SQL Server 实例检查连接字符串Server.代表本机默认实例.\SQLEXPRESS代表命名实例。