教你如何给.Net项目创建本地数据库、建立表,完成增删改查(基于visual stdio)

一、环境配置与模型创建

第1步:新建项目

创建新的项目命名为Exams

 

选择Exams点击运行,测试是否能够运行成功:

如果出现下面界面,代表运行成功:

文件夹的结构如下:

wwwroot 文件夹:包含静态文件,如 HTML 文件、JavaScript 文件和 CSS 文件。

appSettings.json:包含配置数据,如连接字符串。

Program.cs:包含程序的入口点。

第2步:配置环境

添加工具,安装Entity Framework core等...

首先找到要添加依赖的模块,然后右键依赖项,点击管理NuGet程序包:

可以看到<已安装>的工具,在<浏览>输入下面5个工具名进行安装:

1.Microsoft.EntityFrameworkCore

2.Microsoft.EntityFrameworkCore.Sqlite

3.Microsoft.EntityFrameworkCore.SqlServer

4.Microsoft.EntityFrameworkCore.Tools

5.Microsoft.VisualStudio.Web.CodeGeneration.Design

安装结果如下:

其中1、2、4、5必须安装。

第3步:添加数据模型

右键模块,新建文件夹models文件夹和Data文件夹:

 

右键新建的项目-添加-类,新建类ExamSite:

考场表设计如下:

考场表:考场ID,考场名,所属校区,所属楼名,房间号
ExamSiteId ->Int
ExamSiteName -> String
School -> String
Building -> Int
Room -> Int

复制如下代码粘贴入ExamSite.cs,主要是用来定义表的结构:

using System.ComponentModel.DataAnnotations;
namespace Exams.Models;
public class ExamSite
{
    public int ExamSiteId { get; set; }
    public string? ExamSiteName { get; set; }
    public string? School { get; set; }
    public string? Building { get; set; }
    public int? Room { get; set; }
}

二、搭建基架

首先右键Pages文件夹,创建一个Exam文件夹

然后右键Exam文件夹选择添加,选择<新搭建基架的项目>

紧接着选择<使用实体框架生成Razor页面(CURD)>,选择添加。

最后:

1. 在模型类选择ExamSite (Exams.Models)。这个是Models文件夹下的文件。

2, 在数据上下文类中先选中ExamSiteContext(Exams.Data),然后选择+,生成类名Exams.Data.ExamsContext。

选择添加。

 经过大概1分钟的生成,生成了如下文件:

三、修改Program.cs文件

在前一步<数据上下文类>中选择的类名,会在Data文件夹下生成一个新的类:

名字是自动生成的是,一般是<模块名Context.cs>。

我们接下来要在本模块的Program.cs中添加如下代码:

using Exams.Data;

using Exams.Data是为了让Program.cs能够引入ExamsContext文件。

builder.Services.AddDbContext<ExamsContext>(options =>
    options.UseSqlite("Data Source=Exam.db"));

其中ExamsContext就是刚刚自动生成的文件,然后Exam.db是我们想要生成的目标数据库的名字。

四、数据库迁移

在vs中的工具选择NuGet包管理器-程序包管理器控制台

2.输入Add-Migration InitialCreate创建数据表

3.Update-Database

可以看到在模块的末尾出现了一个Exam.db的文件:

将Exam.db文件直接拖到Navicat中可以直接看到该表:

可以发现像ExamSiteId这些字段就是我们在<一>中创建的数据模型中定义的字段。

五、增删改查测试

选择Exam,点击运行项目之后,可以在浏览器地址中加入后缀</文件夹名/文件名>进行访问:

比如在Exam文件夹下有4个类:分别用来增删改查。

Create代表的新增,Edit代表的是修改,如果想要调用新增的界面只需要添加/Exam/Create后缀即可:https://localhost:7110/Exam/Create。

假如我们输入以下的数据进行简单测试:

首先在网页中会出现新增的数据:

然后在数据库中也会实时更新数据:

由此可以推测,数据会被直接插入到Exam.db文件中,并且可以实时进行访问。

下面是增、删、改、查的一些说明:

删、改、查如下:

由此便实现了通过.Net来实现数据库和表的建立以及基本的增删改查。

六、同一数据库中新建多张表

1. 考试表数据结构定义:

考试表:考试ID,考试名,报名开始时间,报名结束时间,排考开始时间,排考结束时间,考试开始时间,考试结束时间

考试表:考试ID,考试名,报名开始时间,报名结束时间,排考开始时间,排考结束时间,考试开始时间,考试结束时间
Exmination表
字段定义如下:
ExamId ->Int
ExamName -> String
SignUpBeginTime -> DateTime
SignUpEndTime -> DateTime
ArrangeExamBeginTime -> DateTime
ArrangeExamEndTime -> DateTime
ExamBeginTime -> DateTime
ExamEndTime -> DateTime
namespace Exams.Models
{
    public class Examination
    {
        public int ExamId { get; set; }
        public string? ExamName { get; set; }
        public DateTime? SignUpBeginTime { get; set; }
        public DateTime? SignUpEndTime { get; set; }
        public DateTime? ArrangeExamBeginTime { get; set; }
        public DateTime? ArrangeExamEndTime { get; set; }
        public DateTime? ExamBeginTime { get; set; }
        public DateTime? ExamEndTime { get; set; }
    }
}

2. 考试-考场关联表数据结构定义:

考试-考场关联表:记录ID,考试ID,考场ID

考试-考场关联表:记录ID,考试ID,考场ID
ExamAndExamSite表
字段定义如下:
recordId -> Int
ExamId -> Int
ExamSiteId -> Int
namespace Exams.Models
{
    public class ExamAndExamSite
    {
        public int recordId { get; set; }
        public int? ExamId { get; set; }
        public int? ExamSiteId { get; set; }
    }
}

在定义完上面3张表的数据模型之后。

第1步:在Pages下再新建两个文件夹Exam1和Exam2,对应关系如下:

Exam -> ExamSite.cs(考场表的增删改查操作)

Exam1 -> Examination.cs(考试表的增删改查操作)

Exam2 -> ExamAndExamSite.cs(考试和考场表的增删改查操作)

第2步:修改Data文件夹下的ExamsContext.cs文件

ExamsContext.cs文件会在对ExamSite生成实体框架后形成:

新的ExamsContext.cs文件的代码如下:

using Microsoft.EntityFrameworkCore;
using Exams.Models;

namespace Exams.Data{
    public class ExamsContext : DbContext{
        public ExamsContext (DbContextOptions<ExamsContext> options)
            : base(options){
        }
        public DbSet<Exams.Models.ExamSite> ExamSite { get; set; } = default!;
        public DbSet<Exams.Models.Examination> Examination { get; set; } = default!;
        //定义了Examination它是DbSet<Examination>类型的,框架会将Examination类与一个表关联起来,表名默认为类名
        public DbSet<Exams.Models.ExamAndExamSite> ExamAndExamSite { get; set; } = default!;

        protected override void OnModelCreating(ModelBuilder modelBuilder){
            modelBuilder.Entity<Examination>().HasKey(e => e.ExamId); // 配置 Examination 的主键
            modelBuilder.Entity<ExamAndExamSite>().HasKey(e => e.recordId); // 配置 ExamAndExamSite 的主键
        }
    }
}

主要新增了另外两张表的定义,以及设定了两张表的主键。

第3步:分别选中Pages文件夹下的Exam、Exam1、Exam2文件夹分别搭建基架,模型类分别选择ExamSite.cs、Examination.cs、ExamAndExamSite.cs这几个文件,数据上下文类一律选择Exams.Data.ExamsContext。

项目的最终结构如下:

   

第4步:按照先前的方式进行数据库迁移,成功后生成Exam.db文件,然后可以放到Navicat中查看,会发现此时Exam.db数据库中已经有了3张表:

ExamSite:考场表如下:

Examination:考试表如下:

ExamAndExamSite:考试-考场表如下:

七、支持API控制器(通过url访问类/方法)

首先要在待运行的模块下面新建一个Controllers文件夹,然后可以在Controllers文件夹下创建一个类,类名最后以Controller结尾:

注意命名空间要写:模块名.文件夹名。public class 类名 :Controller。如下图是一个最基本的程序:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Exams.Data;
using Exams.Models;

namespace Exams.Controllers
{
    [Route("test")] // 基路由,将处理 /test 的请求
    public class WayController : Controller
    {
        [HttpGet("a")] // 完整的路由将变成 /test/a
        public IActionResult Print()
        {
            var data = new { message = "aaa" }; // 创建一个匿名对象作为 JSON 数据
            return Json(data); // 返回 JSON 结果
        }
    }
}

然后千万要注意修改Program.cs,要加入下面两段代码 :

builder.Services.AddControllers();
app.MapControllers();

builder.Services.AddControllers(); // 添加这行以支持API控制器

app.MapControllers(); // 在这里注册API控制器的路由 

然后在url后面加上/test/a即可输出aaa了!

八、获取处于报名期间的所有考试实现

List<Exam> GetActiveExam(DateTime now)接口实现(下午)

接口功能:获取处于报名期间的所有考试

业务逻辑:首先获取当前系统时间now,考试报名开始时间beginTime,考试报名结束时间endTime,beginTime<=now<=endTime。

返回的结果如下:

程序思路:

首先,定义一个函数getNowTime用于获取当前的系统时间:

使用DateTimeOffset函数进行时间的获取。

public DateTimeOffset getNowTime(){
    //DateTime localTime = DateTime.Now;
    DateTimeOffset dateTimeOffset = DateTimeOffset.Now;
    return dateTimeOffset;
}

然后,定义了一个Result结构体,用于存放返回的提示信息和考试表中的数据。 

public struct Result{
    public string response { get; set; }
    public Examination examination { get; set; }
}

 最后是具体的业务逻辑:调用_context.Examination.ToList()获取考试表中所有数据的集合,调用getNowTime获取当前的系统时间。

然后通过foreach循环提取考试表中的每一条数据,将每条数据的报名开始时间和结束时间逐一提取出来。

紧接着判断当前系统时间和开始时间、结束时间之间的大小关系,分为3种情况:1.报名未开始,2.报名已结束,3.报名正在进行中。如果是前两种情况,则考试的详细信息返回为空,如果可以报名,则返回该门考试的详细信息。

下面是完整的代码: 

using Microsoft.AspNetCore.Mvc;
using Exams.Models;

namespace Exams.Controllers{
    [Route("test")] // 基路由,将处理 /test 的请求
    public class WayController : Controller{
        private readonly Exams.Data.ExamsContext _context;
        public struct Result{
            public string response { get; set; }
            public Examination examination { get; set; }
        }
        public WayController(Exams.Data.ExamsContext context){
            _context = context;
        }
        public DateTimeOffset getNowTime(){
            //DateTime localTime = DateTime.Now;
            DateTimeOffset dateTimeOffset = DateTimeOffset.Now;
            return dateTimeOffset;
        }
        [HttpGet("a")]
        public ActionResult<List<Result>> Compare()
        {
            List<Result> finalResult = new List<Result>();
            List<Examination> LIST = _context.Examination.ToList();
            DateTimeOffset nowTime = getNowTime();
            Result result = new Result();
            foreach (Examination list in LIST)
            {
                DateTimeOffset newSignUpBeginTime = new DateTimeOffset((DateTime)list.SignUpBeginTime);
                DateTimeOffset newSignUpEndTime = new DateTimeOffset((DateTime)list.SignUpEndTime);
                if (nowTime < newSignUpBeginTime)
                {
                    result.response = list.ExamId + list.ExamName + ":报名未开始";
                    result.examination = null;
                }
                else if (nowTime > newSignUpEndTime)
                {
                    result.response = list.ExamId + list.ExamName + ":报名已结束";
                    result.examination = null;
                }
                else
                {
                    result.response = list.ExamId + list.ExamName + ":报名成功";
                    result.examination = list;
                }
                finalResult.Add(result);
            }
            return finalResult;
        }
    }   

}

结果如下:

九、其它

4. ExamInfo GetExamInfo(Guid examId);接口实现 + ExamInfo数据结构实现(晚上)

接口功能:获取一场考试,包括这场考试中用到的所有考场。

接口实现逻辑:首先传入一个考试ID,查询考试表,返回该门考试的信息。然后根据考试ID去查询考试-考场表,返回所有与考试ID有关联的考场。

ExamInfo数据结构实现逻辑:包含所有Exam的字段,增加List<Room> Rooms字段表示该场考试所用到的所有考场。

6. Excel导出功能

7. Excel导入功能

6. 搜索功能实现

猜你喜欢

转载自blog.csdn.net/RuanFun/article/details/134712530
今日推荐