ASP.NET Core Web 应用SQLite数据连接显示(1)

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();

📋 完整的数据流总结

  1. 请求发起 → 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  # 项目配置
相关推荐
头茬韭菜1 分钟前
第 3 篇:「Pydantic 即 Schema」—— 工具生态三层解剖
前端·chrome·ai·openmanus
恋猫de小郭22 分钟前
Flutter 状态管理基准测评,一个很有趣的观点
android·前端·flutter
雪芽蓝域zzs28 分钟前
前端编辑组件wangEditor
前端
风骏时光牛马1 小时前
稳定性治理及疑难问题深度剖析与实战复盘
前端
JeffongTan9 小时前
在LWC中镶嵌VF Page获取用户IP
前端·javascript·salesforce
陆枫Larry11 小时前
Astro 是什么
前端
是立不是利13 小时前
写给设计师的 CSS 博客美学指南
前端·css
默_笙14 小时前
🏝 Docker 就是"房地产开发":从施工图纸到小区物业的容器化指南
前端·javascript
计算机魔术师14 小时前
Rohan Paul 谈用时间跨度衡量智能体能力,并引用 OpenAI 自动化研究实习生里程碑
前端