ASP.NET 数据库编程终极指南

目录

  1. 第一部分:基础准备与环境搭建

    asp.net数据库编程教程
    (图片来源网络,侵删)
    • 1 技术栈选择
    • 2 环境安装
    • 3 创建第一个 ASP.NET Core 项目
  2. 第二部分:核心概念 - ADO.NET

    • 1 什么是 ADO.NET?
    • 2 ADO.NET 核心对象 (SqlConnection, SqlCommand, SqlDataReader)
    • 3 完整代码示例:查询数据
    • 4 使用 Dapper 简化 ADO.NET
  3. 第三部分:现代 ORM - Entity Framework Core (EF Core)

    • 1 什么是 ORM?为什么选择 EF Core?
    • 2 EF Core 核心概念 (DbContext, DbSet, Model)
    • 3 步骤一:安装 EF Core 包
    • 4 步骤二:创建数据模型 (Entity)
    • 5 步骤三:创建 DbContext
    • 6 步骤四:配置数据库连接字符串
    • 7 步骤五:创建并应用数据库迁移
    • 8 步骤六:使用 EF Core 进行 CRUD 操作
      • 8.1 查询数据
      • 8.2 创建数据
      • 8.3 更新数据
      • 8.4 删除数据
  4. 第四部分:最佳实践与高级技巧

    • 1 依赖注入
    • 2 异步编程 (async/await)
    • 3 处理并发冲突
    • 4 仓储模式
  5. 第五部分:实战项目 - 构建一个简单的博客系统

    asp.net数据库编程教程
    (图片来源网络,侵删)
    • 1 项目目标
    • 2 创建项目与模型
    • 3 设置数据库
    • 4 创建控制器和视图
    • 5 实现功能
  6. 第六部分:总结与学习资源


第一部分:基础准备与环境搭建

1 技术栈选择

本教程将使用 .NET 6/7/8 (LTS)ASP.NET Core MVC 框架,数据库方面,我们将以 SQL Server 为例,但大部分概念也适用于 PostgreSQL, MySQL, SQLite 等其他 EF Core 支持的数据库。

2 环境安装

  1. .NET SDK: 从 官网 下载并安装最新版的 .NET SDK (推荐 LTS 版本,如 .NET 8)。
  2. Visual Studio 2025: 从 官网 下载安装,在安装程序中,确保勾选了 “.NET 桌面开发”“ASP.NET 和 Web 开发” 工作负载,这会自动安装 SQL Server Express LocalDB。
  3. SQL Server Management Studio (SSMS) (可选但推荐): 用于直接管理和查询数据库,从 官网 下载。

3 创建第一个 ASP.NET Core 项目

  1. 打开 Visual Studio 2025。
  2. 选择 “创建新项目”。
  3. 搜索并选择 “ASP.NET Core Web 应用” 模板,然后点击 “下一步”。
  4. 命名你的项目(MyWebApp),选择一个位置,然后点击 “下一步”。
  5. 选择框架(.NET 8.0 或其他你安装的版本),不要勾选 “使用顶级语句”,然后点击 “创建”。

你已经有了一个可以运行的 ASP.NET Core 项目。


第二部分:核心概念 - ADO.NET

1 什么是 ADO.NET?

ADO.NET 是 .NET 框架中用于与数据源(如数据库)进行交互的一组类库,它是一个底层的、无状态的、基于连接的模型。

核心特点

  • 连接模型: 需要手动建立和关闭数据库连接。
  • 高性能: 因为没有额外的抽象层,所以性能非常高。
  • 灵活: 可以执行任何 SQL 命令,并精细控制数据访问过程。

2 ADO.NET 核心对象

  • SqlConnection: 代表与 SQL Server 数据库的连接。
  • SqlCommand: 代表要执行的 SQL 命令(查询、更新、删除等)。
  • SqlDataReader: 一个只读的、向前的数据流,用于高效读取查询结果。
  • SqlDataAdapter: 用于填充 DataSetDataTable,实现离线数据操作。

3 完整代码示例:查询数据

假设我们有一个 Products 表,我们想从控制器中查询所有产品并传递给视图。

安装 NuGet 包 在解决方案资源管理器中,右键点击 “依赖项” -> “管理 NuGet 程序包”,搜索并安装 Microsoft.Data.SqlClient

修改 HomeController.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;
using System.Data;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration; // 需要注入 IConfiguration
namespace MyWebApp.Controllers
{
    public class HomeController : Controller
    {
        private readonly IConfiguration _configuration;
        public HomeController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        public async Task<IActionResult> Index()
        {
            var products = new List<Product>();
            var connectionString = _configuration.GetConnectionString("DefaultConnection");
            // 使用 using 语句确保资源被正确释放
            using (var connection = new SqlConnection(connectionString))
            {
                await connection.OpenAsync();
                var sql = "SELECT Id, Name, Price FROM Products";
                using (var command = new SqlCommand(sql, connection))
                {
                    using (var reader = await command.ExecuteReaderAsync())
                    {
                        while (await reader.ReadAsync())
                        {
                            products.Add(new Product 
                            { 
                                Id = reader.GetInt32(0), 
                                Name = reader.GetString(1), 
                                Price = reader.GetDecimal(2) 
                            });
                        }
                    }
                }
            }
            return View(products);
        }
    }
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
    }
}

配置连接字符串appsettings.json 中添加你的数据库连接字符串。

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyProductDb;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  // ... 其他配置
}

注意:你需要先在 SQL Server LocalDB 中创建一个名为 MyProductDb 的数据库,并手动创建 Products 表。

创建视图Views/Home 文件夹下,右键 Index.cshtml,用以下代码替换:

@model IEnumerable<MyWebApp.Product>
<h1>产品列表</h1>
<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>名称</th>
            <th>价格</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.Id</td>
                <td>@item.Name</td>
                <td>@item.Price.ToString("C")</td>
            </tr>
        }
    </tbody>
</table>

4 使用 Dapper 简化 ADO.NET

虽然 ADO.NET 很强大,但编写样板代码很繁琐。Dapper 是一个轻量级的“微ORM”,它可以在 ADO.NET 之上提供简单的扩展方法,让你用更少的代码完成同样的事情。

安装 Dapper Install-Package Dapper

重写 HomeController 的 Index 方法

using Dapper;
using Microsoft.Data.SqlClient;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
namespace MyWebApp.Controllers
{
    public class HomeController : Controller
    {
        private readonly IConfiguration _configuration;
        public HomeController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        public async Task<IActionResult> Index()
        {
            var connectionString = _configuration.GetConnectionString("DefaultConnection");
            var sql = "SELECT Id, Name, Price FROM Products";
            using (var connection = new SqlConnection(connectionString))
            {
                // Dapper 的 Query<T> 方法会自动将查询结果映射到 List<T>
                var products = await connection.QueryAsync<Product>(sql);
                return View(products);
            }
        }
        // ... Product 类同上
    }
}

看到了吗?代码量大大减少!Dapper 非常适合对性能有极致要求,但又不希望像纯 ADO.NET 那样繁琐的场景。


第三部分:现代 ORM - Entity Framework Core (EF Core)

1 什么是 ORM?为什么选择 EF Core?

ORM (Object-Relational Mapping) 对象关系映射,是一种程序技术,用于把对象模型表示的对象映射到基于 SQL 的关系模型数据库结构上。

EF Core 的优势

  • 代码优先: 你只需定义 C# 类(模型),EF Core 会为你生成数据库架构。
  • LINQ 查询: 使用 C# 的语言集成查询来查询数据库,而不是写原生 SQL。
  • 自动变更追踪: 当你从数据库加载一个对象后,修改它的属性,EF Core 会自动知道哪些字段被改变了,从而生成正确的 UPDATE 语句。
  • 数据库迁移: 可以轻松地更新数据库架构以匹配你的模型。
  • 解耦: 你的业务逻辑代码不依赖于特定的 SQL 语法,更容易测试和维护。

2 EF Core 核心概念

  • Entity (实体): 对应数据库表的 C# 类(如 Product)。
  • DbContext (上下文): 这是 EF Core 的核心,它负责与数据库交互,并跟踪实体的状态,它通常包含 DbSet<T> 属性。
  • DbSet: 代表数据库中的一个表,可以对它进行查询、添加、删除等操作。

3 步骤一:安装 EF Core 包

在 NuGet 包管理器控制台中运行:

# 对于 SQL Server
Install-Package Microsoft.EntityFrameworkCore.SqlServer
# 用于设计时创建迁移的包
Install-Package Microsoft.EntityFrameworkCore.Tools

4 步骤二:创建数据模型 (Entity)

Models 文件夹下创建 Product.cs

// Models/Product.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MyWebApp.Models
{
    public class Product
    {
        public int Id { get; set; }
        [Required]
        [StringLength(100)]
        public string Name { get; set; }
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }
    }
}

我们添加了数据注解来验证和配置模型。

5 步骤三:创建 DbContext

Models 文件夹下创建 ApplicationDbContext.cs

// Models/ApplicationDbContext.cs
using Microsoft.EntityFrameworkCore;
using MyWebApp.Models;
namespace MyWebApp.Models
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
        public DbSet<Product> Products { get; set; }
    }
}

6 步骤四:配置数据库连接字符串

打开 Program.cs,将 DbContext 注册到依赖注入容器中。

// Program.cs
using Microsoft.EntityFrameworkCore;
using MyWebApp.Models;
var builder = WebApplication.CreateBuilder(args);
// 1. 添加服务到容器。
builder.Services.AddControllersWithViews();
// 2. 注册 DbContext
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
var app = builder.Build();
// ... 其余代码

7 步骤五:创建并应用数据库迁移

  1. 在 Visual Studio 的 “工具” 菜单中,打开 “NuGet 包管理器” -> “包管理器控制台”。

  2. 确保默认项目是你的 ASP.NET Core 项目。

  3. 运行以下命令:

    # 创建初始迁移
    Add-Migration InitialCreate
    # 将迁移应用到数据库
    Update-Database

    执行后,EF Core 会在你的数据库中自动创建一个 Products 表。

8 步骤六:使用 EF Core 进行 CRUD 操作

我们可以修改 HomeController 来使用 EF Core。

修改 HomeController.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MyWebApp.Models;
using System.Threading.Tasks;
namespace MyWebApp.Controllers
{
    public class HomeController : Controller
    {
        private readonly ApplicationDbContext _context;
        // 通过构造函数注入 DbContext
        public HomeController(ApplicationDbContext context)
        {
            _context = context;
        }
        // GET: /Home/Index
        public async Task<IActionResult> Index()
        {
            // 使用 LINQ 查询,EF Core 会将其翻译成 SQL
            var products = await _context.Products.ToListAsync();
            return View(products);
        }
        // GET: /Home/Create
        public IActionResult Create()
        {
            return View();
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("Name,Price")] Product product)
        {
            if (ModelState.IsValid)
            {
                _context.Add(product);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(product);
        }
        // GET: /Home/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            var product = await _context.Products.FindAsync(id);
            if (product == null)
            {
                return NotFound();
            }
            return View(product);
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, [Bind("Id,Name,Price")] Product product)
        {
            if (id != product.Id)
            {
                return NotFound();
            }
            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(product);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ProductExists(product.Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(product);
        }
        // GET: /Home/Delete/5
        public async Task<IActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            var product = await _context.Products
                .FirstOrDefaultAsync(m => m.Id == id);
            if (product == null)
            {
                return NotFound();
            }
            return View(product);
        }
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            var product = await _context.Products.FindAsync(id);
            _context.Products.Remove(product);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        private bool ProductExists(int id)
        {
            return _context.Products.Any(e => e.Id == id);
        }
    }
}

创建对应的视图 (Create.cshtml, Edit.cshtml, Delete.cshtml) 这些视图的创建方式与 Index.cshtml 类似,但包含一个 HTML 表单来输入数据,可以使用 Visual Studio 的 “添加视图” -> “Razor 视图 - 使用实体框架” 功能来自动生成这些视图,非常方便。


第四部分:最佳实践与高级技巧

1 依赖注入

我们已经看到了在 HomeController 中通过构造函数注入 ApplicationDbContext,这是 ASP.NET Core 推荐的做法,它使你的组件更易于测试和解耦。

2 异步编程 (async/await)

所有与数据库交互的 EF Core 和 Dapper 方法都提供了异步版本(以 Async ,在 Web 应用中,始终使用异步方法!这样可以避免阻塞 Web 请求线程,提高服务器的吞吐量和可伸缩性。

// 好的做法
var products = await _context.Products.ToListAsync();
// 不好的做法 (会阻塞线程)
var products = _context.Products.ToList(); 

3 处理并发冲突

当多个用户同时尝试修改同一条数据时,可能会发生并发冲突,EF Core 通过 ConcurrencyCheckRowVersion 属性来处理。

在模型中添加 Timestamp 属性:

[Timestamp]
public byte[] RowVersion { get; set; }

EF Core 会在 UPDATE 语句中包含此列,如果数据库中的值与从实体中读取的值不匹配,就会抛出 DbUpdateConcurrencyException,你可以在 Edit 方法中捕获此异常并提示用户。

4 仓储模式

对于大型项目,通常会创建一个仓储层来封装数据访问逻辑,进一步解耦控制器和 EF Core。

// 仓储接口
public interface IProductRepository
{
    Task<IEnumerable<Product>> GetAllAsync();
    Task<Product> GetByIdAsync(int id);
    // ... 其他方法
}
// EF Core 实现的仓储
public class ProductRepository : IProductRepository
{
    private readonly ApplicationDbContext _context;
    public ProductRepository(ApplicationDbContext context) => _context = context;
    public async Task<IEnumerable<Product>> GetAllAsync() => await _context.Products.ToListAsync();
    public async Task<Product> GetByIdAsync(int id) => await _context.Products.FindAsync(id);
    // ...
}
// 在 Startup.cs/Program.cs 中注册仓储
builder.Services.AddScoped<IProductRepository, ProductRepository>();
// 在 Controller 中使用
public class ProductsController : Controller
{
    private readonly IProductRepository _repository;
    public ProductsController(IProductRepository repository) => _repository = repository;
    // ...
}

第五部分:实战项目 - 构建一个简单的博客系统

这个项目将综合运用 EF Core 和 MVC 知识。

  1. 创建项目: 按照第一部分创建一个新的 ASP.NET Core MVC 项目。
  2. 创建模型:
    • Post.cs: Id, Title, Content, PublishDate
    • Tag.cs: Id, Name
    • PostTag.cs (多对多关系): PostId, TagId
  3. 创建 DbContext: BlogDbContext.cs,包含 DbSet<Post>, DbSet<Tag>, DbSet<PostTag>
  4. 配置依赖注入和迁移: 在 Program.cs 中注册 BlogDbContext,然后使用 PMC 创建并应用迁移。
  5. 创建控制器和视图:
    • PostsController: 实现列表、详情、创建、编辑、删除功能。
    • 为每个 Action 创建对应的 View。
  6. 添加路由和导航: 在 _Layout.cshtml 中添加指向博客列表和创建新文章的链接。

这个项目将让你对整个数据流有更深刻的理解。


第六部分:总结与学习资源

  • ADO.NET/Dapper: 底层、高性能、代码量多,适合性能要求极高或需要执行复杂/特定 SQL 的场景。
  • Entity Framework Core: 现代、高效、开发效率高,绝大多数应用场景下的首选,它为你处理了大部分复杂性,让你能专注于业务逻辑。

学习资源

  • 微软官方文档 (最权威):
  • 视频教程:
    • Philipp Bauknecht (德语,但代码通用): 他的 EF Core 教程非常深入。
    • FreeCodeCamp: 有很多高质量的 ASP.NET Core 全栈教程。
    • Udemy / Pluralsight: 搜索 "ASP.NET Core" 和 "Entity Framework Core",有很多付费和免费课程。
  • 社区:
    • Stack Overflow: 遇到问题,先搜索,大概率能找到答案。
    • GitHub: 查看 EF Core 和 ASP.NET Core 的源码,了解内部实现。

希望这份详细的教程能帮助你顺利掌握 ASP.NET 数据库编程!祝你编码愉快!