1. 首页 > SQLServer教程 > 正文

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 LargeTables { get; set; }

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; }
}

执行结果:

PM> Install-Package System.Data.SqlClient
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 GetByIdAsync(int id);
Task> GetAllAsync();
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 GetByIdAsync(int id)
{
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> GetAllAsync()
{
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 result = new 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 GetByIdAsync(int id)
{
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> GetAllAsync()
{
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 });
}
}
}

执行结果:

PM> Install-Package Dapper
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 LargeTables { get; set; }

public FGEduDbContext(DbContextOptions options) : base(options)
{
}
}


// 在appsettings.json中配置
{
“ConnectionStrings”: {
“DefaultConnection”: “Server=fgedu-server;Database=fgedudb;User Id=fgedu;Password=Password123!;”
}
}

// 在Startup.cs中配置
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext(options =>
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>> GetLargeTables()
{
return await _context.LargeTables.ToListAsync();
}

[HttpGet(“{id}”)]
public async Task> GetLargeTable(int id)
{
var largeTable = await _context.LargeTables.FindAsync(id);
if (largeTable == null)
{
return NotFound();
}
return largeTable;
}

[HttpPost]
public async Task> PostLargeTable(LargeTable largeTable)
{
_context.LargeTables.Add(largeTable);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetLargeTable), new { id = largeTable.Id }, largeTable);
}

[HttpPut(“{id}”)]
public async Task PutLargeTable(int id, LargeTable largeTable)
{
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 DeleteLargeTable(int id)
{
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







执行结果:

$ dotnet new webapi -n FGEduApi
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 GetLargeTablesAsync()
{
// 使用异步方法提高并发性能
var largeTables = await _context.LargeTables.ToListAsync();
return Ok(largeTables);
}


public async Task BulkInsertAsync(List largeTables)
{
// 使用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 GetLargeTablesWithCache()
{
string cacheKey = “largeTables”;
if (_cache.TryGetValue(cacheKey, out List largeTables))
{
return Ok(largeTables);
}

// 从数据库获取数据
largeTables = await _context.LargeTables.ToListAsync();

// 设置缓存,过期时间10分钟
_cache.Set(cacheKey, largeTables, TimeSpan.FromMinutes(10));

return Ok(largeTables);
}


public async Task GetLargeTablesByCol1(string col1)
{
// 使用参数化查询避免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 GetLargeTablesWithRetry()
{
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 GetLargeTablesWithTimeout()
{
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 CreateOrderWithTransaction()
{
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 GetLargeTablesWithLogging()
{
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

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息