1新建项目选择ASP.NET Core Web 应用创建项目名称:QLite数据连接显示

完整数据流程图
用户请求 → 路由系统 → 控制器 → 服务层 → 数据层 → 数据库 → 返回数据 → 视图渲染 → 用户界面
1. 📨 用户请求阶段
用户访问URL
https://localhost:7000/TownVillage/Index
2. 🛣️ 路由匹配阶段
Program.cs 路由配置
app.MapControllerRoute(
name: "default",
pattern: "{controller=TownVillage}/{action=Index}/{id?}");
路由解析结果:
-
Controller:
TownVillageController -
Action:
Index -
Id:
null
3. 🎮 控制器处理阶段
Controllers/TownVillageController.cs
这是一个典型的 ASP.NET Core MVC 控制器,负责处理镇村数据的展示和详情查看功能。
// 引入必要的命名空间
using Microsoft.AspNetCore.Mvc; // 提供MVC控制器相关的类和特性
using QLite数据连接显示.Models; // 引入数据模型类
using QLite数据连接显示.Services; // 引入服务层接口和实现
// 定义控制器的命名空间,通常与项目名称相关
namespace QLite数据连接显示.Controllers
{
/// <summary>
/// 镇村信息控制器
/// 负责处理镇村数据的展示和详情查看功能
/// 继承自Controller基类,获得MVC框架的基础功能
/// </summary>
public class TownVillageController : Controller
{
// 私有只读字段,用于存储镇村服务实例
// readonly确保该字段只能在构造函数中赋值,保证线程安全
private readonly ITownVillageService _townVillageService;
/// <summary>
/// 构造函数 - 依赖注入
/// ASP.NET Core的依赖注入容器会自动注入ITownVillageService的实现
/// </summary>
/// <param name="townVillageService">镇村服务接口实例</param>
public TownVillageController(ITownVillageService townVillageService)
{
// 将注入的服务实例赋值给私有字段
_townVillageService = townVillageService;
}
/// <summary>
/// 镇村列表页面
/// GET请求:/TownVillage/Index
/// 异步方法,使用async/await提高并发性能
/// </summary>
/// <returns>包含镇村列表数据的视图</returns>
public async Task<IActionResult> Index()
{
// 调用服务层获取所有镇村数据
// await关键字非阻塞等待数据库操作完成
var townVillages = await _townVillageService.GetAllTownVillagesAsync();
// 将数据传递给视图
// 默认使用同名的视图文件:Views/TownVillage/Index.cshtml
return View(townVillages);
}
/// <summary>
/// 镇村详情页面
/// GET请求:/TownVillage/Details/5
/// 根据ID查询单个镇村的详细信息
/// </summary>
/// <param name="id">镇村记录的主键ID</param>
/// <returns>
/// - 找到记录:返回包含详情的视图
/// - 未找到记录:返回404 NotFound结果
/// </returns>
public async Task<IActionResult> Details(int id)
{
// 根据ID查询单个镇村记录
var townVillage = await _townVillageService.GetTownVillageByIdAsync(id);
// 检查查询结果是否为null
if (townVillage == null)
{
// 返回404状态码,表示资源未找到
return NotFound();
}
// 将查询到的镇村数据传递给详情视图
// 默认使用同名的视图文件:Views/TownVillage/Details.cshtml
return View(townVillage);
}
}
}
4. 🔧 服务层处理阶段
Services/ITownVillageService.cs
// 引入数据模型命名空间,以便在接口中使用TownVillage模型类
using QLite数据连接显示.Models;
// 定义服务层的命名空间,通常用于存放业务逻辑接口和实现
namespace QLite数据连接显示.Services
{
/// <summary>
/// 镇村信息服务接口
/// 定义镇村数据相关的业务操作契约
/// 遵循接口隔离原则,只暴露必要的方法
/// </summary>
public interface ITownVillageService
{
/// <summary>
/// 获取所有镇村信息列表
/// 异步方法,返回镇村数据的任务
/// </summary>
/// <returns>
/// Task<List<TownVillage>> - 包含镇村列表的异步任务
/// 成功时返回镇村对象列表
/// 失败时抛出异常或返回空列表
/// </returns>
/// <example>
/// 使用示例:
/// <code>
/// var towns = await townService.GetAllTownVillagesAsync();
/// foreach (var town in towns) {
/// Console.WriteLine(town.镇村名称);
/// }
/// </code>
/// </example>
Task<List<TownVillage>> GetAllTownVillagesAsync();
/// <summary>
/// 根据ID获取单个镇村信息
/// 异步方法,用于查询特定镇村的详细信息
/// </summary>
/// <param name="id">镇村记录的主键ID</param>
/// <returns>
/// Task<TownVillage> - 包含单个镇村对象的异步任务
/// 找到记录时返回TownVillage对象
/// 未找到记录时返回null
/// </returns>
/// <example>
/// 使用示例:
/// <code>
/// var town = await townService.GetTownVillageByIdAsync(1);
/// if (town != null) {
/// ViewBag.Name = town.镇村名称;
/// }
/// </code>
/// </example>
Task<TownVillage> GetTownVillageByIdAsync(int id);
}
}
Services/TownVillageService.cs
// 引入必要的命名空间
using Microsoft.EntityFrameworkCore; // Entity Framework Core 功能
using QLite数据连接显示.Models; // 数据模型类
// 服务层的命名空间
namespace QLite数据连接显示.Services
{
/// <summary>
/// 镇村服务实现类
/// 实现 ITownVillageService 接口,提供具体的镇村数据操作
/// 负责与数据库交互的业务逻辑
/// </summary>
public class TownVillageService : ITownVillageService
{
// 私有只读字段,存储数据库上下文实例
// 通过依赖注入获取,用于数据库操作
private readonly AppDbContext _context;
/// <summary>
/// 构造函数 - 依赖注入数据库上下文
/// </summary>
/// <param name="context">数据库上下文实例</param>
public TownVillageService(AppDbContext context)
{
// 注入的数据库上下文赋值给私有字段
_context = context;
}
/// <summary>
/// 获取所有镇村信息列表
/// 异步方法,从数据库查询所有镇村记录
/// </summary>
/// <returns>
/// 按ID排序的镇村列表
/// 如果表中无数据,返回空列表
/// </returns>
public async Task<List<TownVillage>> GetAllTownVillagesAsync()
{
// 使用 Entity Framework Core 进行数据库查询
return await _context.镇村表 // 从镇村表查询
.OrderBy(t => t.id) // 按ID字段升序排序
.ToListAsync(); // 异步执行查询并返回列表
}
/// <summary>
/// 根据ID获取单个镇村信息
/// 异步方法,根据主键ID查询特定镇村记录
/// </summary>
/// <param name="id">要查询的镇村主键ID</param>
/// <returns>
/// 找到则返回 TownVillage 对象
/// 未找到则返回 null
/// </returns>
public async Task<TownVillage> GetTownVillageByIdAsync(int id)
{
// 根据ID查询单个镇村记录
return await _context.镇村表
.FirstOrDefaultAsync(t => t.id == id); // 查找第一个匹配ID的记录或返回null
}
}
}
5. 🗄️ 数据层处理阶段
Models/AppDbContext.cs
// 引入必要的命名空间
using Microsoft.EntityFrameworkCore; // Entity Framework Core 核心功能
using QLite数据连接显示.Models; // 数据模型类
// 主项目命名空间
namespace QLite数据连接显示
{
/// <summary>
/// 应用程序数据库上下文类
/// 继承自 DbContext,是 Entity Framework Core 的核心类
/// 负责与数据库的交互和实体配置
/// </summary>
public class AppDbContext : DbContext
{
/// <summary>
/// 构造函数
/// 通过依赖注入接收 DbContextOptions 配置选项
/// </summary>
/// <param name="options">数据库上下文配置选项</param>
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
// 调用基类构造函数,传递配置选项
// 这些选项包括数据库连接字符串、数据库提供程序等
}
/// <summary>
/// 镇村表 DbSet 属性
/// 表示数据库中的"镇村表"集合
/// 通过这个属性可以进行CRUD操作
/// </summary>
public DbSet<TownVillage> 镇村表 { get; set; }
/// <summary>
/// 模型创建配置方法
/// 在模型创建时被调用,用于配置实体与数据库表的映射关系
/// </summary>
/// <param name="modelBuilder">模型构建器,用于配置实体模型</param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 调用基类方法,确保基类的配置也被执行
base.OnModelCreating(modelBuilder);
// 配置 TownVillage 实体与数据库表的映射关系
modelBuilder.Entity<TownVillage>(entity =>
{
entity.ToTable("镇村表"); // 指定实体映射到的表名
entity.HasKey(e => e.id); // 指定实体的主键字段
entity.Property(e => e.id).ValueGeneratedOnAdd(); // 配置主键为自增
});
}
}
}
Models/TownVillage.cs
// 引入数据注解命名空间,用于数据验证和映射配置
using System.ComponentModel.DataAnnotations; // 提供数据验证特性
using System.ComponentModel.DataAnnotations.Schema; // 提供数据库映射特性
// 模型层的命名空间,包含数据实体类
namespace QLite数据连接显示.Models
{
/// <summary>
/// 镇村实体类
/// 映射到数据库中的"镇村表"
/// 使用数据注解配置数据库映射和验证规则
/// </summary>
[Table("镇村表")] // 指定实体类映射的数据库表名
public class TownVillage
{
/// <summary>
/// 主键ID
/// 唯一标识每条镇村记录
/// </summary>
[Key] // 标识此属性为主键
[Display(Name = "ID")] // 指定在UI中显示的名称
public int id { get; set; }
/// <summary>
/// 子区编码
/// 行政区划编码,标识具体的子区域
/// </summary>
[Required] // 必填字段验证,不能为null或空字符串
[Display(Name = "子区编码")] // 在UI标签中显示为"子区编码"
public string 子区编码 { get; set; }
/// <summary>
/// 编号
/// 镇村的编号标识
/// </summary>
[Required] // 必填字段
[Display(Name = "编号")] // UI显示名称
public string 编号 { get; set; }
/// <summary>
/// 编号01
/// 辅助编号字段,用于进一步的分类或排序
/// </summary>
[Required] // 必填字段
[Display(Name = "编号01")] // UI显示名称
public int 编号01 { get; set; }
/// <summary>
/// 镇村名称
/// 镇或村的正式名称
/// </summary>
[Required] // 必填字段
[Display(Name = "镇村名称")] // UI显示名称
public string 镇村名称 { get; set; }
}
}
6. 💾 数据库操作阶段
Entity Framework Core 生成的SQL
ServicesTownVillageService.cs
// 引入必要的命名空间
using Microsoft.EntityFrameworkCore; // Entity Framework Core 功能
using QLite数据连接显示.Models; // 数据模型类
// 服务层的命名空间
namespace QLite数据连接显示.Services
{
/// <summary>
/// 镇村服务实现类
/// 实现 ITownVillageService 接口,提供镇村数据的业务逻辑操作
/// 作为数据访问层和表示层之间的桥梁
/// </summary>
public class TownVillageService : ITownVillageService
{
// 私有只读字段,存储数据库上下文实例
// 通过依赖注入获取,用于所有数据库操作
private readonly AppDbContext _context;
/// <summary>
/// 构造函数 - 依赖注入模式
/// ASP.NET Core 的DI容器会自动注入 AppDbContext 实例
/// </summary>
/// <param name="context">数据库上下文实例</param>
public TownVillageService(AppDbContext context)
{
// 验证输入参数(生产环境建议添加)
_context = context ?? throw new ArgumentNullException(nameof(context));
}
/// <summary>
/// 获取所有镇村信息列表
/// 异步方法,从数据库查询所有镇村记录并按ID排序
/// </summary>
/// <returns>
/// Task<List<TownVillage>> - 包含镇村列表的异步任务
/// 成功:返回按ID排序的镇村列表
/// 空表:返回空列表(Count = 0)
/// 异常:抛出数据库相关异常
/// </returns>
/// <example>
/// 使用示例:
/// <code>
/// var service = new TownVillageService(context);
/// var towns = await service.GetAllTownVillagesAsync();
/// foreach (var town in towns) {
/// Console.WriteLine($"{town.id}: {town.镇村名称}");
/// }
/// </code>
/// </example>
public async Task<List<TownVillage>> GetAllTownVillagesAsync()
{
// 使用 Entity Framework Core 的 LINQ 查询
return await _context.镇村表 // 从镇村表 DbSet 开始查询
.OrderBy(t => t.id) // 按 ID 字段升序排序
.ToListAsync(); // 异步执行查询并返回 List
}
/// <summary>
/// 根据ID获取单个镇村信息
/// 异步方法,根据主键ID查询特定的镇村记录
/// </summary>
/// <param name="id">要查询的镇村记录主键ID</param>
/// <returns>
/// Task<TownVillage> - 包含单个镇村对象的异步任务
/// 找到记录:返回 TownVillage 对象
/// 未找到记录:返回 null
/// 异常:抛出数据库相关异常
/// </returns>
/// <example>
/// 使用示例:
/// <code>
/// var service = new TownVillageService(context);
/// var town = await service.GetTownVillageByIdAsync(1);
/// if (town != null) {
/// Console.WriteLine($"找到镇村: {town.镇村名称}");
/// } else {
/// Console.WriteLine("未找到对应的镇村记录");
/// }
/// </code>
/// </example>
public async Task<TownVillage> GetTownVillageByIdAsync(int id)
{
// 根据ID查询单个记录
return await _context.镇村表
.FirstOrDefaultAsync(t => t.id == id); // 查找第一个匹配的记录或返回null
}
}
}
7. 📊 数据返回阶段
数据流向
text
数据库记录 → Entity Framework → TownVillage对象列表 → 服务层 → 控制器 → 视图模型
8. 🎨 视图渲染阶段
Views/TownVillage/Index.cshtml
html
@model IEnumerable<QLite数据连接显示.Models.TownVillage>
@{
ViewData["Title"] = "镇村列表";
}
<div class="container">
<h2>镇村列表</h2>
<table class="table table-striped table-bordered">
<thead class="thead-dark">
<tr>
<th>@Html.DisplayNameFor(model => model.First().id)</th>
<th>@Html.DisplayNameFor(model => model.First().子区编码)</th>
<th>@Html.DisplayNameFor(model => model.First().编号)</th>
<th>@Html.DisplayNameFor(model => model.First().编号01)</th>
<th>@Html.DisplayNameFor(model => model.First().镇村名称)</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => item.id)</td>
<td>@Html.DisplayFor(modelItem => item.子区编码)</td>
<td>@Html.DisplayFor(modelItem => item.编号)</td>
<td>@Html.DisplayFor(modelItem => item.编号01)</td>
<td>@Html.DisplayFor(modelItem => item.镇村名称)</td>
<td>
<a href="@Url.Action("Details", new { id = item.id })" class="btn btn-info btn-sm">详情</a>
</td>
</tr>
}
</tbody>
</table>
<div class="mt-3">
<p>共 @Model.Count() 条记录</p>
</div>
</div>
Views/TownVillage/Details.cshtml
html
@model 宅基地管理系统.Models.TownVillage
@{
ViewData["Title"] = "镇村详情";
}
<div class="container">
<h2>镇村详情</h2>
<hr />
<dl class="row">
<dt class="col-sm-3">@Html.DisplayNameFor(model => model.id)</dt>
<dd class="col-sm-9">@Html.DisplayFor(model => model.id)</dd>
<dt class="col-sm-3">@Html.DisplayNameFor(model => model.子区编码)</dt>
<dd class="col-sm-9">@Html.DisplayFor(model => model.子区编码)</dd>
<dt class="col-sm-3">@Html.DisplayNameFor(model => model.编号)</dt>
<dd class="col-sm-9">@Html.DisplayFor(model => model.编号)</dd>
<dt class="col-sm-3">@Html.DisplayNameFor(model => model.编号01)</dt>
<dd class="col-sm-9">@Html.DisplayFor(model => model.编号01)</dd>
<dt class="col-sm-3">@Html.DisplayNameFor(model => model.镇村名称)</dt>
<dd class="col-sm-9">@Html.DisplayFor(model => model.镇村名称)</dd>
</dl>
<div class="mt-3">
<a href="@Url.Action("Index")" class="btn btn-secondary">返回列表</a>
</div>
</div>
9. ⚙️ 应用程序启动阶段
Program.cs (完整代码)
csharp
using Microsoft.EntityFrameworkCore;
using QLite数据连接显示;
using QLite数据连接显示.Models;
using QLite数据连接显示.Services;
var builder = WebApplication.CreateBuilder(args);
// 添加服务到容器
builder.Services.AddControllersWithViews();
// 配置数据库上下文
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlite("Data Source=宅基地管理.db"));
// 注册服务
builder.Services.AddScoped<ITownVillageService, TownVillageService>();
var app = builder.Build();
// 配置HTTP请求管道
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=TownVillage}/{action=Index}/{id?}");
app.Run();
📋 完整的数据流总结
- 请求发起 → 2. 路由解析 → 3. 控制器接收 → 4. 服务调用 → 5. 数据库查询 → 6. 数据处理 → 7. 视图渲染 → 8. HTML响应
这个完整的数据流展示了ASP.NET Core MVC应用程序从接收用户请求到返回HTML页面的全过程,每个阶段都有相应的代码实现。
宅基地管理系统/
├── Controllers/ # 控制器层
│ └── TownVillageController.cs
├── Models/ # 数据模型层
│ ├── AppDbContext.cs
│ └── TownVillage.cs
├── Services/ # 服务层
│ ├── ITownVillageService.cs
│ └── TownVillageService.cs
├── Views/ # 视图层
│ └── TownVillage/
│ ├── Index.cshtml
│ └── Details.cshtml
├── Program.cs # 应用程序入口
└── 宅基地管理系统.csproj # 项目配置