ASP.NET Core 作为微软推出的一个高性能、跨平台的开源 Web 开发框架,凭借其强大的功能和灵活的扩展性,受到了广大开发者的青睐。它不仅支持多种编程语言,还提供了丰富的中间件和工具,帮助开发者快速构建高效、可靠的 Web 应用。
在实际开发中,数据库操作是 Web 应用的核心功能之一。Dapper 是一个轻量级的 ORM(对象关系映射)工具,它能够高效地将数据库表与 C# 对象进行映射,同时保持代码的简洁性和高性能。Dapper 的使用可以大大简化数据库操作的复杂性,提高开发效率,尤其适合于需要高性能和灵活操作的场景。
前端页面的用户体验同样至关重要。Layui 是一个基于 HTML5 的前端 UI 框架,它提供了丰富的 UI 组件和简洁的样式,能够快速搭建出美观、易用的前端页面。通过 Layui 的表格组件,可以方便地实现数据的展示、分页、排序等功能,提升用户的交互体验。
本教程将结合 ASP.NET Core 8 MVC、Dapper ORM 和 Layui 框架,通过一个完整的实战项目——Book 管理系统,详细讲解如何实现 SQL Server 数据库中 Book
表的增、删、改、查操作。我们将从项目搭建、数据库设计、后端开发到前端页面实现,逐步展开,帮助读者掌握 ASP.NET Core 8 MVC 的开发流程和技巧,以及如何使用 Dapper ORM 和 Layui 框架进行高效开发。通过本教程的学习,读者将能够快速上手并应用到实际项目中,提升开发能力。
1. 项目搭建与环境配置
1.1 创建 ASP.NET Core 8 MVC 项目
-
打开 Visual Studio 2022 或更高版本,选择“创建新项目”。
-
在项目类型中选择“ASP.NET Core Web 应用程序”,点击“下一步”。
-
输入项目名称(如 BookManagementSystem),选择项目保存位置,点击“创建”。
-
在项目模板中选择“MVC”,确保目标框架为“.NET 8.0”,点击“创建”完成项目创建。
1.2 安装 Dapper 和 SQL Server 驱动
-
在解决方案资源管理器中右键点击项目名称,选择“管理 NuGet 包”。
-
在 NuGet 包管理器中搜索并安装以下包:
-
Dapper
:用于简化数据库操作的 ORM 工具。 -
Microsoft.Data.SqlClient
:用于连接 SQL Server 数据库的驱动程序。
-
-
安装完成后,可以在项目的
Dependencies
中看到已安装的包。
1.3 配置数据库连接字符串
-
打开项目的
appsettings.json
文件。 -
在
ConnectionStrings
节点中添加数据库连接字符串,示例如下:"ConnectionStrings": { "DefaultConnection": "Server=你的服务器地址;Database=你的数据库名称;User Id=你的用户名;Password=你的密码;" }
-
在
Program.cs
文件中,通过Configuration
读取连接字符串,并在ConfigureServices
方法中注册数据库连接,示例如下:using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.EntityFrameworkCore; using System.Data.SqlClient; using Dapper; var builder = WebApplication.CreateBuilder(args); // 从 appsettings.json 中读取连接字符串 var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); // 配置数据库上下文 builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); // 添加其他服务 builder.Services.AddControllersWithViews(); var app = builder.Build(); // 配置中间件 if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
-
通过上述配置,项目可以正确连接到 SQL Server 数据库,并为后续的数据库操作提供支持。
2. 数据库设计与表创建
2.1 设计 Book 表结构
在设计 Book 表时,需要考虑存储书籍的基本信息,包括书名、作者、出版日期、价格等字段。以下是 Book 表的结构设计:
-
Id
:主键,使用int
类型,自增。 -
Title
:书名,使用nvarchar(255)
类型,非空。 -
Author
:作者,使用nvarchar(255)
类型,非空。 -
PublishDate
:出版日期,使用datetime
类型,非空。 -
Price
:价格,使用decimal(18,2)
类型,非空。 -
Description
:描述,使用nvarchar(max)
类型,可空。 根据以上设计,Book 表的结构可以满足存储书籍基本信息的需求,方便后续进行增、删、改、查操作。
2.2 初始化 SQL Server 数据库
在 SQL Server 数据库中创建 Book 表,可以使用以下 SQL 脚本:
CREATE TABLE Book (
Id INT PRIMARY KEY IDENTITY(1,1),
Title NVARCHAR(255) NOT NULL,
Author NVARCHAR(255) NOT NULL,
PublishDate DATETIME NOT NULL,
Price DECIMAL(18,2) NOT NULL,
Description NVARCHAR(MAX)
);
执行上述脚本后,Book 表将被创建在数据库中,为后续的开发工作做好准备。
3. DapperHelper 帮助类开发
3.1 创建 DapperHelper 类
在项目中创建一个名为 DapperHelper.cs
的类文件,用于封装数据库操作的通用方法。该类将提供数据库连接、执行 SQL 语句、查询数据等功能,以简化后续的数据库操作代码。
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Threading.Tasks;
public static class DapperHelper
{
// 数据库连接字符串
private static readonly string ConnectionString = "Server=你的服务器地址;Database=你的数据库名称;User Id=你的用户名;Password=你的密码;";
// 获取数据库连接
private static IDbConnection GetConnection()
{
return new SqlConnection(ConnectionString);
}
}
3.2 实现数据库连接与关闭方法
在 DapperHelper
类中,实现数据库连接的打开和关闭方法,确保每次操作数据库时都能正确管理连接资源。
public static class DapperHelper
{
private static readonly string ConnectionString = "Server=你的服务器地址;Database=你的数据库名称;User Id=你的用户名;Password=你的密码;";
private static IDbConnection GetConnection()
{
return new SqlConnection(ConnectionString);
}
// 打开数据库连接
private static IDbConnection OpenConnection()
{
var connection = GetConnection();
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
return connection;
}
// 关闭数据库连接
private static void CloseConnection(IDbConnection connection)
{
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
}
}
3.3 封装增删改查通用方法
在 DapperHelper
类中,封装增删改查的通用方法,以便在后续的业务逻辑中直接调用这些方法,减少重复代码。
using Microsoft.Data.SqlClient;
using System.Data;
using Dapper;
namespace BookManagementSystem.Common
{
public static class DapperHelper
{
static DapperHelper()
{
// 从配置文件中读取连接字符串
var configuration = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json")
.Build();
ConnectionString = configuration.GetConnectionString("DefaultConnection");
}
private static readonly string ConnectionString ;
private static IDbConnection GetConnection()
{
return new SqlConnection(ConnectionString);
}
private static IDbConnection OpenConnection()
{
var connection = GetConnection();
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
return connection;
}
private static void CloseConnection(IDbConnection connection)
{
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
}
// 插入数据
public static int Insert<T>(string sql, T parameters)
{
using (var connection = OpenConnection())
{
var result = connection.Execute(sql, parameters);
CloseConnection(connection);
return result;
}
}
// 更新数据
public static int Update<T>(string sql, T parameters)
{
using (var connection = OpenConnection())
{
var result = connection.Execute(sql, parameters);
CloseConnection(connection);
return result;
}
}
// 删除数据
public static int Delete(string sql, object parameters)
{
using (var connection = OpenConnection())
{
var result = connection.Execute(sql, parameters);
CloseConnection(connection);
return result;
}
}
// 查询单条数据
public static T QueryFirstOrDefault<T>(string sql, object parameters = null)
{
using (var connection = OpenConnection())
{
var result = connection.QueryFirstOrDefault<T>(sql, parameters);
CloseConnection(connection);
return result;
}
}
// 查询多条数据
public static List<T> Query<T>(string sql, object parameters = null)
{
using (var connection = OpenConnection())
{
var result = connection.Query<T>(sql, parameters).ToList();
CloseConnection(connection);
return result;
}
}
}
}
通过上述封装,DapperHelper
类提供了通用的数据库操作方法,使得在后续的业务逻辑中可以更加方便地进行增删改查操作,同时保证了代码的简洁性和可维护性。
4. 后端开发
4.1 创建 Book 模型类
在项目中创建一个名为 Book.cs
的类文件,用于定义书籍的模型类。该类将包含与数据库中 Book
表对应的属性,代码如下:
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime PublishDate { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
}
通过定义 Book
模型类,可以方便地在代码中表示和操作书籍数据,使其与数据库表结构保持一致,为后续的业务逻辑开发提供基础。
4.2 创建 Book 服务类
在项目中创建一个名为 BookService.cs
的类文件,用于封装与书籍相关的业务逻辑。该类将依赖于 DapperHelper
类来实现对数据库的操作,代码如下:
using System.Collections.Generic;
using System.Linq;
public class BookService
{
// 获取所有书籍
public List<Book> GetAllBooks()
{
string sql = "SELECT * FROM Book";
return DapperHelper.Query<Book>(sql);
}
// 根据 ID 获取书籍
public Book GetBookById(int id)
{
string sql = "SELECT * FROM Book WHERE Id = @Id";
return DapperHelper.QueryFirstOrDefault<Book>(sql, new { Id = id });
}
// 添加书籍
public int AddBook(Book book)
{
string sql = "INSERT INTO Book (Title, Author, PublishDate, Price, Description) VALUES (@Title, @Author, @PublishDate, @Price, @Description)";
return DapperHelper.Insert(sql, book);
}
// 更新书籍
public int UpdateBook(Book book)
{
string sql = "UPDATE Book SET Title = @Title, Author = @Author, PublishDate = @PublishDate, Price = @Price, Description = @Description WHERE Id = @Id";
return DapperHelper.Update(sql, book);
}
// 删除书籍
public int DeleteBook(int id)
{
string sql = "DELETE FROM Book WHERE Id = @Id";
return DapperHelper.Delete(sql, new { Id = id });
}
}
通过创建 BookService
类,将书籍相关的业务逻辑集中管理,使得代码更加清晰和易于维护。同时,利用 DapperHelper
类提供的通用方法,可以高效地实现对数据库的增删改查操作,提高开发效率。
4.3 实现 Book 控制器
在项目中创建一个名为 BooksController.cs
的控制器文件,用于处理与书籍相关的 HTTP 请求。该控制器将依赖于 BookService
类来实现具体的业务逻辑,代码如下:
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
public class BooksController : Controller
{
private readonly BookService _bookService;
public BooksController()
{
_bookService = new BookService();
}
// 获取所有书籍
[HttpGet]
public IActionResult Index()
{
List<Book> books = _bookService.GetAllBooks();
return View(books);
}
// 添加书籍
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(Book book)
{
if (ModelState.IsValid)
{
_bookService.AddBook(book);
return RedirectToAction("Index");
}
return View(book);
}
// 编辑书籍
[HttpGet]
public IActionResult Edit(int id)
{
Book book = _bookService.GetBookById(id);
if (book == null)
{
return NotFound();
}
return View(book);
}
[HttpPost]
public IActionResult Edit(Book book)
{
if (ModelState.IsValid)
{
_bookService.UpdateBook(book);
return RedirectToAction("Index");
}
return View(book);
}
// 删除书籍
[HttpGet]
public IActionResult Delete(int id)
{
Book book = _bookService.GetBookById(id);
if (book == null)
{
return NotFound();
}
return View(book);
}
[HttpPost]
public IActionResult DeleteConfirmed(int id)
{
_bookService.DeleteBook(id);
return RedirectToAction("Index");
}
}
通过实现 BooksController
控制器,可以将前端页面的请求与后端的业务逻辑进行有效的连接。控制器中的每个方法对应一种 HTTP 请求类型和业务操作,通过调用 BookService
类中的方法来完成具体的数据库操作,从而实现书籍的增删改查功能。同时,利用 ASP.NET Core MVC 的路由机制和视图引擎,可以方便地生成和管理前端页面,为用户提供良好的交互体验。
5. 前端开发
5.1 引入 Layui 框架
在 ASP.NET Core 8 MVC 项目中引入 Layui 框架,可以方便地实现前端页面的美化和功能增强。具体步骤如下:
-
在项目的
wwwroot
文件夹中创建一个名为layui
的文件夹,用于存放 Layui 相关资源。 -
从 Layui 官方网站下载最新版本的 Layui 压缩包,解压后将其中的
css
和js
文件夹复制到wwwroot/layui
文件夹中。 -
在
_Layout.cshtml
文件中引入 Layui 的 CSS 和 JavaScript 文件,代码如下:<!-- 引入 Layui CSS --> <link rel="stylesheet" href="~/layui/css/layui.css" media="all"> <!-- 引入 Layui JavaScript --> <script src="~/layui/layui.js" charset="utf-8"></script>
通过上述步骤,Layui 框架将被成功引入到项目中,为后续的前端页面开发提供支持。
5.2 创建 Book 列表页面
创建一个名为 Index.cshtml
的视图文件,用于展示书籍列表页面。在该页面中,使用 Layui 的表格组件来显示书籍数据,并添加操作按钮用于编辑和删除书籍。代码如下:
@model List<Book>
@{
ViewData["Title"] = "书籍列表";
}
<h2>书籍列表</h2>
<!-- 添加书籍按钮 -->
<button class="layui-btn" onclick="window.location.href='/Books/Create'">添加书籍</button>
<!-- 表格容器 -->
<table id="bookTable" lay-filter="bookTableFilter"></table>
@section Scripts {
<script>
layui.use(['table'], function () {
var table = layui.table;
// 初始化表格
table.render({
elem: '#bookTable',
url: '/Books/GetBooks', // 数据接口
cols: [[ // 表头
{ field: 'id', title: 'ID', width: 50, sort: true },
{ field: 'title', title: '书名', width: 150 },
{ field: 'author', title: '作者', width: 150 },
{ field: 'publishDate', title: '出版日期', width: 150, sort: true },
{ field: 'price', title: '价格', width: 100, sort: true },
{ field: 'description', title: '描述', width: 200 },
{ field: 'right', title: '操作', width: 150, toolbar: '#operationBar' }
]],
page: true // 开启分页
});
// 操作栏模板
var operationBar = document.getElementById('operationBar');
operationBar.innerHTML = '<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>' +
'<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete">删除</a>';
// 监听操作栏事件
table.on('tool(bookTableFilter)', function (obj) {
var data = obj.data; // 获取当前行的数据
var layEvent = obj.event; // 获取 lay-event 对应的值
var tr = obj.tr; // 获取当前行 tr 的 DOM 对象
if (layEvent === 'edit') {
window.location.href = '/Books/Edit/' + data.id; // 跳转到编辑页面
} else if (layEvent === 'delete') {
layer.confirm('确定要删除这本书吗?', function (index) {
$.post('/Books/DeleteConfirmed', { id: data.id }, function (result) {
if (result.success) {
layer.msg('删除成功');
table.reload(); // 刷新表格
} else {
layer.msg('删除失败');
}
});
});
}
});
});
</script>
}
在上述代码中,使用 Layui 的表格组件 table
来渲染书籍数据,并通过 url
属性指定数据接口 /Books/GetBooks
,该接口将在后端通过 BookService
类获取书籍数据并返回 JSON 格式。同时,在表格的每一行中添加了操作按钮,用于编辑和删除书籍,通过监听操作栏事件来实现相应的功能。
5.3 实现表格数据加载与操作
为了实现表格数据的加载和操作功能,需要在后端添加一个名为 GetBooks
的方法,用于返回书籍数据的 JSON 格式。在 BooksController.cs
文件中添加以下代码:
// 获取书籍数据
[HttpGet]
public IActionResult GetBooks()
{
List<Book> books = _bookService.GetAllBooks();
return Json(new { code = 0, msg = "", data = books });
}
在上述代码中,GetBooks
方法调用 BookService
类的 GetAllBooks
方法获取所有书籍数据,并将其包装成 Layui 表格所需的 JSON 格式返回。
对于编辑和删除操作,已经在前端页面的 JavaScript 代码中通过监听操作栏事件实现了。当点击编辑按钮时,会跳转到编辑页面;当点击删除按钮时,会弹出确认框,确认后通过发送 POST 请求到 /Books/DeleteConfirmed
方法来删除书籍。在 BooksController.cs
文件中,DeleteConfirmed
方法已经实现了删除书籍的逻辑。
通过上述步骤,实现了书籍列表页面的表格数据加载与操作功能,用户可以在前端页面中方便地查看、编辑和删除书籍信息。
6. 测试与优化
6.1 测试增删改查功能
在完成 ASP.NET Core 8 MVC 项目开发后,需要对书籍的增删改查功能进行全面测试,确保系统的稳定性和可靠性。以下是测试的具体步骤和方法:
-
添加书籍测试:
-
打开浏览器,访问书籍列表页面,点击“添加书籍”按钮,跳转到添加书籍页面。
-
在添加书籍表单中,输入书名、作者、出版日期、价格等信息,点击“提交”按钮。
-
检查数据库中是否成功插入了一条新的书籍记录,同时检查页面是否正确跳转回书籍列表页面,并显示新增的书籍信息。
-
测试边界条件,如输入空的书名或作者,检查系统是否能够正确提示用户输入错误信息。
-
-
编辑书籍测试:
-
在书籍列表页面,选择一本书籍,点击“编辑”按钮,跳转到编辑书籍页面。
-
修改书籍的部分信息,如书名或价格,点击“提交”按钮。
-
检查数据库中对应的书籍记录是否被正确更新,同时检查页面是否正确跳转回书籍列表页面,并显示更新后的书籍信息。
-
测试编辑功能的边界条件,如将价格设置为负数或输入非法的日期格式,检查系统是否能够正确处理并提示用户。
-
-
删除书籍测试:
-
在书籍列表页面,选择一本书籍,点击“删除”按钮,弹出确认框。
-
点击“确定”按钮,检查数据库中对应的书籍记录是否被正确删除,同时检查页面是否正确刷新并移除了该书籍信息。
-
点击“取消”按钮,检查书籍信息是否保持不变,确保删除操作的可撤销性。
-
-
查询书籍测试:
-
在书籍列表页面,通过分页功能查看不同页码的书籍数据,检查分页功能是否正常工作。
-
检查表格中显示的书籍信息是否与数据库中的记录一致,包括书名、作者、出版日期、价格等字段。
-
测试表格的排序功能,如点击“出版日期”或“价格”列标题,检查表格是否能够按照相应的字段进行升序或降序排序。
-
通过上述测试步骤,可以全面验证书籍增删改查功能的正确性和稳定性,确保系统能够满足用户的基本操作需求。
6.2 性能优化与异常处理
在系统测试过程中,除了功能测试外,还需要关注系统的性能和异常处理能力,以提升用户体验和系统的可靠性。以下是性能优化和异常处理的具体措施:
-
性能优化:
-
数据库查询优化:在
BookService
类中,对 SQL 查询语句进行优化,避免使用复杂的嵌套查询和大量的数据扫描。例如,在获取书籍列表时,可以使用索引来加速查询速度,减少数据库的响应时间。 -
缓存机制:对于一些不经常变动的数据,如书籍列表,可以引入缓存机制。使用 ASP.NET Core 的内存缓存或分布式缓存(如 Redis),将书籍数据缓存起来,减少对数据库的直接查询次数,提高系统的响应速度。
-
异步操作:在控制器中,将数据库操作改为异步方法,如使用
Task
和async/await
关键字。这样可以避免阻塞主线程,提高系统的并发处理能力,提升用户体验。 -
前端优化:在前端页面中,对 Layui 表格的渲染进行优化,减少不必要的 DOM 操作。例如,通过分页功能限制每次显示的书籍数量,避免一次性加载过多数据导致页面卡顿。
-
-
异常处理:
-
全局异常处理:在
Startup.cs
文件中,配置全局异常处理中间件,捕获系统运行时的异常。当发生异常时,记录异常信息到日志文件中,并向用户显示友好的错误提示页面,避免直接将异常信息暴露给用户。 -
数据库异常处理:在
DapperHelper
类中,对数据库操作的异常进行捕获和处理。例如,在执行 SQL 语句时,如果发生数据库连接失败或 SQL 语法错误,记录详细的异常信息,并抛出自定义的异常,以便在上层业务逻辑中进行统一处理。 -
业务逻辑异常处理:在
BookService
类中,对业务逻辑的异常进行处理。例如,在添加书籍时,如果发现书名或作者为空,抛出自定义的业务异常,并在控制器中捕获该异常,向用户提示输入错误信息。
-
通过性能优化和异常处理措施的实施,可以显著提升系统的性能和稳定性,为用户提供更加流畅和可靠的使用体验。
7. 总结
通过上述章节的详细阐述,我们已经完成了一个基于 ASP.NET Core 8 MVC 的实战开发项目,实现了对 SQL Server 数据库中 Book
表的增、删、改、查操作,并使用 Dapper ORM 进行数据库操作,同时利用 Layui 框架美化前端页面并实现数据展示。
在项目开发过程中,我们从项目搭建与环境配置开始,逐步完成了数据库设计、DapperHelper 帮助类开发、后端业务逻辑实现以及前端页面开发。通过合理的分层架构设计,我们将项目分为数据访问层、业务逻辑层和表示层,使得代码结构清晰、易于维护和扩展。
在数据访问层,我们通过 DapperHelper 类封装了通用的数据库操作方法,包括增、删、改、查等,提高了代码的复用性和开发效率。在业务逻辑层,我们创建了 BookService 类,集中管理与书籍相关的业务逻辑,通过调用 DapperHelper 类实现对数据库的具体操作。在表示层,我们利用 ASP.NET Core MVC 的路由机制和视图引擎,结合 Layui 框架的表格组件,实现了书籍列表的展示、添加、编辑和删除功能,为用户提供了良好的交互体验。
在开发过程中,我们注重代码的规范性和可读性,遵循了良好的编程习惯。同时,我们也对系统的性能和异常处理进行了优化和处理,通过数据库查询优化、缓存机制、异步操作以及全局异常处理等措施,提升了系统的性能和稳定性,确保了用户在使用过程中的流畅体验。
通过本项目的实战开发,读者可以深入理解 ASP.NET Core 8 MVC 的开发流程和技巧,掌握 Dapper ORM 的使用方法,以及 Layui 框架在前端页面开发中的应用。希望本教程能够为读者在实际项目开发中提供有价值的参考和借鉴。