SQLServer教程FG037-SQLServer .NET集成实战
目录大纲
内容简介
本文档基于SQLServer官方文档的.NET集成内容,结合生产环境实际情况,详细讲解SQLServer与.NET的集成配置、数据访问、性能优化等内容。风哥教程参考SQLServer官方文档.NET Framework Data Provider for SQL Server、SQL Server Native Client等相关章节。
Part01-基础概念与理论知识
1.1 SQLServer .NET集成概念
SQLServer .NET集成的概念:
- SQLServer与.NET的集成是指通过.NET Framework或.NET Core与SQLServer进行数据交互
- 主要通过ADO.NET、Entity Framework等技术实现
- 支持同步和异步数据访问
- 提供了丰富的API和工具,简化数据库操作
更多视频教程www.fgedu.net.cn
1.2 SQLServer .NET驱动介绍
SQLServer .NET驱动介绍:
- System.Data.SqlClient:传统的.NET Framework数据提供程序,适用于.NET Framework
- Microsoft.Data.SqlClient:新一代的.NET数据提供程序,适用于.NET Core和.NET 5+
- Entity Framework Core:ORM框架,提供对象关系映射功能
- Dapper:轻量级ORM框架,性能优异,使用简单
学习交流加群风哥微信: itpux-com
1.3 SQLServer .NET集成架构
SQLServer .NET集成架构:
- 应用层:.NET应用程序,如ASP.NET网站、Windows服务等
- 数据访问层:负责与数据库交互,如ADO.NET、Entity Framework等
- 连接层:处理数据库连接、连接池管理等
- 数据库层:SQLServer数据库实例
学习交流加群风哥QQ113257174
Part02-生产环境规划与建议
2.1 SQLServer .NET集成规划原则
集成规划原则:
- 根据应用类型和规模选择合适的数据访问技术
- 设计合理的数据访问层架构,确保可维护性和可扩展性
- 考虑并发访问和事务处理需求
- 制定连接池和性能优化策略
- 确保数据安全和错误处理机制
风哥提示:生产环境应根据实际需求选择合适的.NET集成方案,平衡性能和开发效率
2.2 SQLServer .NET连接池配置
连接池配置:
- Max Pool Size:连接池最大连接数,默认100
- Min Pool Size:连接池最小连接数,默认0
- Connection Timeout:连接超时时间,默认15秒
- Idle Timeout:空闲连接超时时间,默认60秒
- Load Balance Timeout:负载均衡超时时间,默认30秒
更多学习教程公众号风哥教程itpux_com
2.3 SQLServer .NET性能优化建议
性能优化建议:
- 使用参数化查询,避免SQL注入和提高性能
- 合理使用连接池,减少连接开销
- 使用异步操作,提高应用响应速度
- 批量操作,减少网络往返
- 缓存常用数据,减少数据库访问
- 优化SQL语句,提高查询性能
from SQLServer视频:www.itpux.com
Part03-生产环境项目实施方案
3.1 SQLServer .NET集成配置
集成配置:
Install-Package System.Data.SqlClient
Install-Package Microsoft.Data.SqlClient
using System.Data.SqlClient;
string connectionString = ConfigurationManager.ConnectionStrings[“DefaultConnection”].ConnectionString;
// 步骤4:创建数据库连接
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// 执行数据库操作
}
Install-Package Microsoft.EntityFrameworkCore.SqlServer
public class FGEduDbContext : DbContext
{
public DbSet
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(“Server=fgedu-server;Database=fgedudb;User Id=fgedu;Password=Password123!;”);
}
}
public class LargeTable
{
public int Id { get; set; }
public string Col1 { get; set; }
public string Col2 { get; set; }
}
执行结果:
Successfully installed ‘System.Data.SqlClient’ to FGEduApp
PM> Install-Package Microsoft.Data.SqlClient
Successfully installed ‘Microsoft.Data.SqlClient’ to FGEduApp
PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer
Successfully installed ‘Microsoft.EntityFrameworkCore.SqlServer’ to FGEduApp
3.2 SQLServer .NET数据访问层实现
数据访问层实现:
public interface ILargeTableRepository
{
Task
Task
Task AddAsync(LargeTable entity);
Task UpdateAsync(LargeTable entity);
Task DeleteAsync(int id);
}
public class LargeTableRepository : ILargeTableRepository
{
private readonly string _connectionString;
public LargeTableRepository(string connectionString)
{
_connectionString = connectionString;
}
public async Task
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
string sql = “SELECT Id, Col1, Col2 FROM fgedu.large_table WHERE Id = @Id”;
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue(“@Id”, id);
await connection.OpenAsync();
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
if (await reader.ReadAsync())
{
return new LargeTable
{
Id = reader.GetInt32(0),
Col1 = reader.GetString(1),
Col2 = reader.GetString(2)
};
}
return null;
}
}
}
}
public async Task
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
string sql = “SELECT Id, Col1, Col2 FROM fgedu.large_table”;
using (SqlCommand command = new SqlCommand(sql, connection))
{
await connection.OpenAsync();
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
List
while (await reader.ReadAsync())
{
result.Add(new LargeTable
{
Id = reader.GetInt32(0),
Col1 = reader.GetString(1),
Col2 = reader.GetString(2)
});
}
return result;
}
}
}
}
public async Task AddAsync(LargeTable entity)
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
string sql = “INSERT INTO fgedu.large_table (Col1, Col2) VALUES (@Col1, @Col2)”;
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue(“@Col1”, entity.Col1);
command.Parameters.AddWithValue(“@Col2”, entity.Col2);
await connection.OpenAsync();
await command.ExecuteNonQueryAsync();
}
}
}
public async Task UpdateAsync(LargeTable entity)
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
string sql = “UPDATE fgedu.large_table SET Col1 = @Col1, Col2 = @Col2 WHERE Id = @Id”;
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue(“@Id”, entity.Id);
command.Parameters.AddWithValue(“@Col1”, entity.Col1);
command.Parameters.AddWithValue(“@Col2”, entity.Col2);
await connection.OpenAsync();
await command.ExecuteNonQueryAsync();
}
}
}
public async Task DeleteAsync(int id)
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
string sql = “DELETE FROM fgedu.large_table WHERE Id = @Id”;
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue(“@Id”, id);
await connection.OpenAsync();
await command.ExecuteNonQueryAsync();
}
}
}
}
Install-Package Dapper
public class LargeTableRepositoryDapper : ILargeTableRepository
{
private readonly string _connectionString;
public LargeTableRepositoryDapper(string connectionString)
{
_connectionString = connectionString;
}
public async Task
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
await connection.OpenAsync();
return await connection.QueryFirstOrDefaultAsync
“SELECT Id, Col1, Col2 FROM fgedu.large_table WHERE Id = @Id”,
new { Id = id });
}
}
public async Task
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
await connection.OpenAsync();
return await connection.QueryAsync
“SELECT Id, Col1, Col2 FROM fgedu.large_table”);
}
}
public async Task AddAsync(LargeTable entity)
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
await connection.OpenAsync();
await connection.ExecuteAsync(
“INSERT INTO fgedu.large_table (Col1, Col2) VALUES (@Col1, @Col2)”,
entity);
}
}
public async Task UpdateAsync(LargeTable entity)
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
await connection.OpenAsync();
await connection.ExecuteAsync(
“UPDATE fgedu.large_table SET Col1 = @Col1, Col2 = @Col2 WHERE Id = @Id”,
entity);
}
}
public async Task DeleteAsync(int id)
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
await connection.OpenAsync();
await connection.ExecuteAsync(
“DELETE FROM fgedu.large_table WHERE Id = @Id”,
new { Id = id });
}
}
}
执行结果:
Successfully installed ‘Dapper’ to FGEduApp
// 数据访问层测试结果
// GetByIdAsync: 返回ID为1的记录
// GetAllAsync: 返回所有记录
// AddAsync: 成功添加新记录
// UpdateAsync: 成功更新记录
// DeleteAsync: 成功删除记录
3.3 SQLServer .NET事务管理
事务管理:
using (SqlConnection connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
using (SqlTransaction transaction = connection.BeginTransaction())
{
try
{
// 执行第一个操作
string sql1 = “INSERT INTO fgedu.large_table (Col1, Col2) VALUES (@Col1, @Col2)”;
using (SqlCommand command1 = new SqlCommand(sql1, connection, transaction))
{
command1.Parameters.AddWithValue(“@Col1”, “test1”);
command1.Parameters.AddWithValue(“@Col2”, “value1”);
await command1.ExecuteNonQueryAsync();
}
// 执行第二个操作
string sql2 = “UPDATE fgedu.large_table SET Col2 = @Col2 WHERE Col1 = @Col1”;
using (SqlCommand command2 = new SqlCommand(sql2, connection, transaction))
{
command2.Parameters.AddWithValue(“@Col1”, “test1”);
command2.Parameters.AddWithValue(“@Col2”, “updated”);
await command2.ExecuteNonQueryAsync();
}
// 提交事务
transaction.Commit();
Console.WriteLine(“事务提交成功”);
}
catch (Exception ex)
{
// 回滚事务
transaction.Rollback();
Console.WriteLine(“事务回滚: ” + ex.Message);
}
}
}
using (FGEduDbContext context = new FGEduDbContext())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
// 添加新记录
var newRecord = new LargeTable { Col1 = “test2”, Col2 = “value2” };
context.LargeTables.Add(newRecord);
await context.SaveChangesAsync();
// 更新记录
var existingRecord = await context.LargeTables.FirstOrDefaultAsync(t => t.Col1 == “test2”);
if (existingRecord != null)
{
existingRecord.Col2 = “updated2”;
await context.SaveChangesAsync();
}
// 提交事务
await transaction.CommitAsync();
Console.WriteLine(“EF事务提交成功”);
}
catch (Exception ex)
{
// 回滚事务
await transaction.RollbackAsync();
Console.WriteLine(“EF事务回滚: ” + ex.Message);
}
}
}
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
try
{
// 执行数据库操作
using (SqlConnection connection1 = new SqlConnection(connectionString))
{
await connection1.OpenAsync();
string sql1 = “INSERT INTO fgedu.large_table (Col1, Col2) VALUES (@Col1, @Col2)”;
using (SqlCommand command1 = new SqlCommand(sql1, connection1))
{
command1.Parameters.AddWithValue(“@Col1”, “test3”);
command1.Parameters.AddWithValue(“@Col2”, “value3”);
await command1.ExecuteNonQueryAsync();
}
}
using (SqlConnection connection2 = new SqlConnection(connectionString))
{
await connection2.OpenAsync();
string sql2 = “UPDATE fgedu.large_table SET Col2 = @Col2 WHERE Col1 = @Col1”;
using (SqlCommand command2 = new SqlCommand(sql2, connection2))
{
command2.Parameters.AddWithValue(“@Col1”, “test3”);
command2.Parameters.AddWithValue(“@Col2”, “updated3”);
await command2.ExecuteNonQueryAsync();
}
}
// 提交事务
scope.Complete();
Console.WriteLine(“TransactionScope事务提交成功”);
}
catch (Exception ex)
{
// 自动回滚
Console.WriteLine(“TransactionScope事务回滚: ” + ex.Message);
}
}
执行结果:
EF事务提交成功
TransactionScope事务提交成功
Part04-生产案例与实战讲解
4.1 SQLServer .NET集成案例
集成实战:
dotnet new webapi -n FGEduApi
cd FGEduApi
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson
public class LargeTable
{
public int Id { get; set; }
public string Col1 { get; set; }
public string Col2 { get; set; }
}
public class FGEduDbContext : DbContext
{
public DbSet
public FGEduDbContext(DbContextOptions
{
}
}
// 在appsettings.json中配置
{
“ConnectionStrings”: {
“DefaultConnection”: “Server=fgedu-server;Database=fgedudb;User Id=fgedu;Password=Password123!;”
}
}
// 在Startup.cs中配置
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext
options.UseSqlServer(Configuration.GetConnectionString(“DefaultConnection”)));
services.AddControllers().AddNewtonsoftJson();
}
[ApiController]
[Route(“api/[controller]”)]
public class LargeTableController : ControllerBase
{
private readonly FGEduDbContext _context;
public LargeTableController(FGEduDbContext context)
{
_context = context;
}
[HttpGet]
public async Task
{
return await _context.LargeTables.ToListAsync();
}
[HttpGet(“{id}”)]
public async Task
{
var largeTable = await _context.LargeTables.FindAsync(id);
if (largeTable == null)
{
return NotFound();
}
return largeTable;
}
[HttpPost]
public async Task
{
_context.LargeTables.Add(largeTable);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetLargeTable), new { id = largeTable.Id }, largeTable);
}
[HttpPut(“{id}”)]
public async Task
{
if (id != largeTable.Id)
{
return BadRequest();
}
_context.Entry(largeTable).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!LargeTableExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
[HttpDelete(“{id}”)]
public async Task
{
var largeTable = await _context.LargeTables.FindAsync(id);
if (largeTable == null)
{
return NotFound();
}
_context.LargeTables.Remove(largeTable);
await _context.SaveChangesAsync();
return NoContent();
}
private bool LargeTableExists(int id)
{
return _context.LargeTables.Any(e => e.Id == id);
}
}
dotnet run
执行结果:
The template “ASP.NET Core Web API” was created successfully.
$ cd FGEduApi
$ dotnet add package Microsoft.EntityFrameworkCore.SqlServer
Writing C:\Users\User\AppData\Local\Temp\tmpE2C4.tmp
$ dotnet add package Microsoft.EntityFrameworkCore.Design
Writing C:\Users\User\AppData\Local\Temp\tmpF3D5.tmp
$ dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson
Writing C:\Users\User\AppData\Local\Temp\tmp9E4B.tmp
$ dotnet run
Building…
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
[
{“id”: 1, “col1”: “test1”, “col2”: “value1”},
{“id”: 2, “col1”: “test2”, “col2”: “value2”}
]
{“id”: 1, “col1”: “test1”, “col2”: “value1”}
4.2 SQLServer .NET性能优化案例
性能优化实战:
public async Task
{
// 使用异步方法提高并发性能
var largeTables = await _context.LargeTables.ToListAsync();
return Ok(largeTables);
}
public async Task
{
// 使用SqlBulkCopy进行批量插入
using (SqlConnection connection = new SqlConnection(_connectionString))
{
await connection.OpenAsync();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
bulkCopy.DestinationTableName = “fgedu.large_table”;
bulkCopy.ColumnMappings.Add(“Col1”, “Col1”);
bulkCopy.ColumnMappings.Add(“Col2”, “Col2”);
// 创建DataTable
DataTable dataTable = new DataTable();
dataTable.Columns.Add(“Col1”, typeof(string));
dataTable.Columns.Add(“Col2”, typeof(string));
foreach (var item in largeTables)
{
dataTable.Rows.Add(item.Col1, item.Col2);
}
await bulkCopy.WriteToServerAsync(dataTable);
}
}
return Ok();
}
private static MemoryCache _cache = new MemoryCache(new MemoryCacheOptions());
public async Task
{
string cacheKey = “largeTables”;
if (_cache.TryGetValue(cacheKey, out List
{
return Ok(largeTables);
}
// 从数据库获取数据
largeTables = await _context.LargeTables.ToListAsync();
// 设置缓存,过期时间10分钟
_cache.Set(cacheKey, largeTables, TimeSpan.FromMinutes(10));
return Ok(largeTables);
}
public async Task
{
// 使用参数化查询避免SQL注入并提高性能
var largeTables = await _context.LargeTables.Where(t => t.Col1 == col1).ToListAsync();
return Ok(largeTables);
}
// 在连接字符串中配置连接池
“Server=fgedu-server;Database=fgedudb;User Id=fgedu;Password=Password123!;Max Pool Size=200;Min Pool Size=20;Connection Timeout=30;”
// 在数据库中创建索引
CREATE INDEX IX_large_table_col1 ON fgedu.large_table(Col1);
执行结果:
4.3 SQLServer .NET故障处理案例
故障处理实战:
public async Task
{
int retryCount = 3;
int delay = 1000;
for (int i = 0; i < retryCount; i++)
{
try
{
var largeTables = await _context.LargeTables.ToListAsync();
return Ok(largeTables);
}
catch (SqlException ex) when (ex.Number == 10054 || ex.Number == 10060 || ex.Number == 233)
{
// 连接错误,重试
if (i < retryCount - 1)
{
await Task.Delay(delay);
delay *= 2;
continue;
}
return StatusCode(503, "数据库连接失败");
}
catch (Exception ex)
{
return StatusCode(500, "服务器内部错误: " + ex.Message);
}
}
return StatusCode(503, "数据库连接失败");
}
public async Task
{
try
{
// 设置查询超时时间
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)))
{
var largeTables = await _context.LargeTables.ToListAsync(cts.Token);
return Ok(largeTables);
}
}
catch (OperationCanceledException)
{
return StatusCode(408, “查询超时”);
}
catch (Exception ex)
{
return StatusCode(500, “服务器内部错误: ” + ex.Message);
}
}
public async Task
{
using (var transaction = await _context.Database.BeginTransactionAsync())
{
try
{
// 创建订单
var order = new Order { OrderDate = DateTime.Now, CustomerId = 1 };
_context.Orders.Add(order);
await _context.SaveChangesAsync();
// 创建订单明细
var orderDetail = new OrderDetail { OrderId = order.Id, ProductId = 1, Quantity = 10 };
_context.OrderDetails.Add(orderDetail);
await _context.SaveChangesAsync();
// 提交事务
await transaction.CommitAsync();
return Ok(order);
}
catch (Exception ex)
{
// 回滚事务
await transaction.RollbackAsync();
return StatusCode(500, “事务执行失败: ” + ex.Message);
}
}
}
public async Task
{
try
{
var largeTables = await _context.LargeTables.ToListAsync();
return Ok(largeTables);
}
catch (Exception ex)
{
// 记录错误日志
_logger.LogError(ex, “获取大表数据失败”);
return StatusCode(500, “服务器内部错误”);
}
}
执行结果:
Part05-风哥经验总结与分享
5.1 SQLServer .NET集成最佳实践
SQLServer .NET集成最佳实践:
- 选择合适的驱动:根据.NET版本选择合适的SQLServer驱动
- 使用异步操作:提高应用的并发性能和响应速度
- 合理配置连接池:根据应用规模和并发需求配置连接池
- 使用参数化查询:避免SQL注入并提高查询性能
- 实现事务管理:确保数据操作的一致性和完整性
- 添加错误处理:提高应用的可靠性和容错能力
- 使用缓存:减少数据库访问,提高应用性能
- 优化SQL语句:提高查询效率,减少数据库负载
更多视频教程www.fgedu.net.cn
5.2 SQLServer .NET常见问题
常见问题:
- 连接超时:检查网络连接、SQLServer服务状态和连接字符串配置
- 连接池耗尽:检查连接是否正确释放,调整连接池大小
- SQL注入:使用参数化查询和存储过程
- 性能问题:优化SQL语句、使用索引、实现缓存
- 事务死锁:优化事务范围,避免长时间锁定资源
- 内存泄漏:确保正确释放数据库连接和资源
学习交流加群风哥微信: itpux-com
5.3 SQLServer .NET性能优化
性能优化:
- 使用批量操作:对于大量数据操作,使用SqlBulkCopy提高性能
- 实现数据分页:避免一次返回过多数据
- 使用索引视图:提高复杂查询的性能
- 优化连接字符串:合理配置连接池和超时设置
- 使用异步编程:充分利用系统资源,提高并发处理能力
- 监控和分析:使用性能监控工具分析瓶颈,针对性优化
学习交流加群风哥QQ113257174
风哥提示:SQLServer与.NET的集成是企业应用开发的重要组成部分,合理的集成方案和性能优化策略可以显著提高应用的可靠性和性能。
更多学习教程公众号风哥教程itpux_com
from SQLServer视频:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
