WPF开发学生信息管理系统【WPF+Prism+MAH+WebApi】(二)

最近通过WPF开发项目,为了对WPF知识点进行总结,所以利用业余时间,开发一个学生信息管理系统【Student Information Management System】。上一篇文章进行了框架搭建和模块划分,本文在前一篇基础之上,继续深入开发学生信息管理系统的数据库和WebApi接口搭建相关内容,仅供学习分享使用,如有不足之处,还请指正。

涉及知识点

本篇内容主要是数据库的操作和WebApi的创建,涉及到知识点如下所示:

  • 数据库知识,基于SQL Server 2012的数据表创建,以及CRUD【(Create)、检索(Retrieve)、更新(Update)和删除(Delete)】等基础操作。
  • WebApi接口创建基础操作,本文会涉及到通过WebApi提供数据接口给客户端,用于封装数据持久化的操作。

数据库相关

在学生信息管理系统中,学生,班级,课程,成绩等内容和管理模块的相关内容,都离不开数据库的支持,所以数据是支撑,页面是对数据的展示。数据库结构,如下所示:

主要涉及的表如下所示:

1. 学生表Student

学生表主要存储学生的基础信息,如下所示:

学生表创建语句,如下所示:

USE [SIMS]
GO

/****** Object:  Table [dbo].[Students]    Script Date: 2022/5/25 0:11:41 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Students](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [No] [varchar](50) NULL,
    [Name] [varchar](50) NULL,
    [Age] [int] NULL,
    [Sex] [bit] NULL,
    [ClassesId] [int] NULL,
    [CreateUser] [int] NULL,
    [CreateTime] [datetime] NULL,
    [LastEditUser] [int] NULL,
    [LastEditTime] [datetime] NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

2. 班级表Classes

班级表主要用于保存班级相关信息,如下所示:

 班级表创建语句,如下所示:

USE [SIMS]
GO

/****** Object:  Table [dbo].[Classes]    Script Date: 2022/5/25 0:16:31 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Classes](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
    [Dept] [varchar](50) NULL,
    [Grade] [varchar](50) NULL,
    [HeadTeacher] [varchar](50) NULL,
    [Monitor] [int] NULL,
    [CreateUser] [int] NULL,
    [CreateTime] [datetime] NULL,
    [LastEditUser] [int] NULL,
    [LastEditTime] [datetime] NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

3. 课程表Courses

课程表主要保存课程信息,如下所示:

 课程表创建语句,如下所示:

USE [SIMS]
GO

/****** Object:  Table [dbo].[Courses]    Script Date: 2022/5/25 0:20:11 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Courses](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
    [Teacher] [varchar](50) NULL,
    [CreateUser] [int] NULL,
    [CreateTime] [datetime] NULL,
    [LastEditUser] [int] NULL,
    [LastEditTime] [datetime] NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

4. 成绩表Scores

成绩表用于保存学生各科的成绩,如下所示:

 成绩表创建语句,如下所示:

USE [SIMS]
GO

/****** Object:  Table [dbo].[Scores]    Script Date: 2022/5/25 0:23:19 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Scores](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [StudentId] [int] NULL,
    [CourseId] [int] NULL,
    [Score] [float] NULL,
    [CreateUser] [int] NULL,
    [CreateTime] [datetime] NULL,
    [LastEditUser] [int] NULL,
    [LastEditTime] [datetime] NULL
) ON [PRIMARY]

GO

5. 其他数据表

其他数据表包括用户表【Users】,角色表【Roles】,用户角色对应关系表【UserRoles】,角色菜单对应关系表【RoleMenus】菜单表【Menus】 创建语句,如下所示:

USE [SIMS]
GO

/****** Object:  Table [dbo].[Users]    Script Date: 2022/5/25 0:29:55 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Users](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [UserName] [varchar](50) NULL,
    [Password] [varchar](50) NULL,
    [NickName] [varchar](50) NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO
------------------------------------------
USE [SIMS]
GO

/****** Object:  Table [dbo].[Roles]    Script Date: 2022/5/25 0:30:21 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Roles](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
    [Description] [varchar](50) NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO
------------------------------------------
USE [SIMS]
GO

/****** Object:  Table [dbo].[Menus]    Script Date: 2022/5/25 0:31:04 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Menus](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
    [Description] [varchar](50) NULL,
    [Url] [varchar](250) NULL,
    [ParentId] [int] NULL,
    [SortId] [int] NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

------------------------------------------
USE [SIMS]
GO

/****** Object:  Table [dbo].[UserRoles]    Script Date: 2022/5/25 0:31:20 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[UserRoles](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NULL,
    [RoleId] [int] NULL
) ON [PRIMARY]

GO
------------------------------------------
USE [SIMS]
GO

/****** Object:  Table [dbo].[RoleMenus]    Script Date: 2022/5/25 0:31:35 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[RoleMenus](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [RoleId] [int] NULL,
    [MenuId] [int] NULL
) ON [PRIMARY]

GO

数据库实体类

数据库实体类是数据库表与类的映射,通过操作实体类来达到操作数据库的目的,实体类需要与EntityFramework结合起来使用。如下所示:

1. 学生类StudentEntity

学生类与学生表对应,如下所示:

namespace SIMS.Entity
{
    /// <summary>
    /// 学生实体
    /// </summary>
    public class StudentEntity
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 学号
        /// </summary>
        public string No { get; set; }

        /// <summary>
        /// 学生名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 年纪
        /// </summary>
        public int Age { get; set; }

        /// <summary>
        /// 性别
        /// </summary>
        public Boolean Sex { get; set; }

        /// <summary>
        /// 班级标识
        /// </summary>
        public int? ClassesId { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime? CreateTime { get; set; }

        /// <summary>
        /// 当前登录的账号的ID
        /// </summary>
        public int? CreateUser { get; set; }

        /// <summary>
        /// 最后编辑时间
        /// </summary>
        public DateTime? LastEditTime { get; set; }

        /// <summary>
        /// 最后修改人
        /// </summary>
        public int? LastEditUser { get; set; }
    }
}

2. 班级类ClassesEntity

班级类与班级表对应,如下所示:

namespace SIMS.Entity
{
    /// <summary>
    /// 班级实体
    /// </summary>
    public class ClassesEntity
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 专业
        /// </summary>
        public string Dept { get; set; }

        /// <summary>
        /// 年级
        /// </summary>
        public string Grade { get; set; }

        /// <summary>
        /// 班级名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 班主任老师名称
        /// </summary>
        public string HeadTeacher { get; set; }

        /// <summary>
        /// 班长id,对应学生表的学生
        /// </summary>
        public int? Monitor { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 当前登录的账号的ID
        /// </summary>
        public int CreateUser { get; set; }

        /// <summary>
        /// 最后编辑时间
        /// </summary>
        public DateTime LastEditTime { get; set; }

        /// <summary>
        /// 最后修改人
        /// </summary>
        public int LastEditUser { get; set; }
    }
}

3. 课程类CourseEntity

课程类与课程表对应,如下所示:

namespace SIMS.Entity
{
    /// <summary>
    /// 课程实体
    /// </summary>
    public class CourseEntity
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 课程名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 授课老师
        /// </summary>
        public string Teacher { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 当前登录的账号的ID
        /// </summary>
        public int CreateUser { get; set; }

        /// <summary>
        /// 最后编辑时间
        /// </summary>
        public DateTime LastEditTime { get; set; }

        /// <summary>
        /// 最后修改人
        /// </summary>
        public int LastEditUser { get; set; }
    }
}

4. 成绩类ScoreEntity

成绩类与成绩表对应,如下所示:

namespace SIMS.Entity
{
    /// <summary>
    /// 成绩实体
    /// </summary>
    public class ScoreEntity
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        ///学生id
        /// </summary>
        public int StudentId { get; set; }

        /// <summary>
        /// 课程id
        /// </summary>
        public int CourseId { get; set; }

        /// <summary>
        /// 成绩
        /// </summary>
        public double Score { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 当前登录的账号的ID
        /// </summary>
        public int CreateUser { get; set; }

        /// <summary>
        /// 最后编辑时间
        /// </summary>
        public DateTime LastEditTime { get; set; }

        /// <summary>
        /// 最后修改人
        /// </summary>
        public int LastEditUser { get; set; }
    }
}

5. 其他实体类

除了以上四个主要的实体类,还有其他实体类,如下所示:

菜单实体MenuEntity,如下所示:

namespace SIMS.Entity
{
    /// <summary>
    /// 菜单管理
    /// </summary>
    public class MenuEntity
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 菜单名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 菜单描述
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 菜单路径
        /// </summary>
        public string Url { get; set; }

        /// <summary>
        /// 父ID
        /// </summary>
        public int? ParentId { get; set; }

        /// <summary>
        /// 排序
        /// </summary>
        public int? SortId { get; set; }
    }
}

用户实体类UserEntity,如下所示:

namespace SIMS.Entity
{
    public class UserEntity
    {
        /// <summary>
        /// 用户唯一标识
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 登录账号
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; set; }

        /// <summary>
        /// 显示名称
        /// </summary>
        public string NickName { get; set; }
    }
}

角色实体类RoleEntity,如下所示:

namespace SIMS.Entity
{
    /// <summary>
    /// 角色
    /// </summary>
    public class RoleEntity
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 角色名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 角色描述
        /// </summary>
        public string Description { get; set; }
    }
}

用户角色关系实体类UserRoleEntityr,如下所示:

namespace SIMS.Entity
{
    /// <summary>
    /// 用户-角色模型
    /// </summary>
    public class UserRoleEntity
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 用户ID
        /// </summary>
        public int UserId { get; set; }

        /// <summary>
        /// 角色ID
        /// </summary>
        public int RoleId { get; set; }
    }
}

角色菜单关系实体RoleMenuEntity,如下所示:

namespace SIMS.Entity
{
    /// <summary>
    /// 角色-菜单关联
    /// </summary>
    public class RoleMenuEntity
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 菜单IP
        /// </summary>
        public int MenuId { get; set; }

        /// <summary>
        /// 角色ID
        /// </summary>
        public int RoleId { get; set; }
    }
}

一共九个实体类,对应数据库中的九个表。

WebApi数据接口

在本示例中,客户端和服务端交互通过webapi接口进行,避免直接操作数据库。具体步骤如下所示:

1. EntityFramework框架

EntityFramework是.Net领域通用的ORM框架,有CodeFirst和DBFirst两种方式,本文采用DBFirst方式,即先设计数据库表结构,再创建实体和映射。如果要使用EntityFramework框架,首先进行安装,可通过NuGet包管理器进行安装,如下所示:

 创建DataContext数据操作类,继承自DbContext,并重写OnModelCreating方法,将数据表和实体类建立联系,实现映射,如下所示:

namespace SIMS.WebApi.Data
{
    public class DataContext:DbContext
    {
        public DbSet<UserEntity> Users { get; set; }

        public DbSet<MenuEntity> Menus { get; set; }

        public DbSet<RoleEntity> Roles { get; set; }

        public DbSet<UserRoleEntity> UserRoles { get; set; }

        public DbSet<RoleMenuEntity> RoleMenus { get; set; }

        /// <summary>
        /// 学生
        /// </summary>
        public DbSet<StudentEntity> Students { get; set; }

        /// <summary>
        /// 班级
        /// </summary>
        public DbSet<ClassesEntity> Classes { get; set; }

        /// <summary>
        /// 课程
        /// </summary>
        public DbSet<CourseEntity> Courses { get; set; }

        /// <summary>
        /// 成绩
        /// </summary>
        public DbSet<ScoreEntity> Scores { get; set; }

        public DataContext(DbContextOptions options) : base(options)
        {

        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<UserEntity>().ToTable("Users");
            modelBuilder.Entity<MenuEntity>().ToTable("Menus");
            modelBuilder.Entity<StudentEntity>().ToTable("Students");
            modelBuilder.Entity<RoleEntity>().ToTable("Roles");
            modelBuilder.Entity<UserRoleEntity>().ToTable("UserRoles");
            modelBuilder.Entity<RoleMenuEntity>().ToTable("RoleMenus");
        }
    }
}

2. 创建服务

在本示例中,为了封装数据库的底层操作,提取了四个服务接口和类,如下所示:

学生服务接口IStudentAppService,是对学生表操作的封装,如下所示:

namespace SIMS.WebApi.Services.Student
{
    public interface IStudentAppService
    {
        /// <summary>
        /// 查询学生列表
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public PagedRequest<StudentEntity> GetStudents(string no,string name, int pageNum, int pageSize);

        /// <summary>
        /// 查询某一班级的学生列表
        /// </summary>
        /// <param name="classId"></param>
        /// <returns></returns>
        public PagedRequest<StudentEntity> GetStudentsByClasses(int classId);

        /// <summary>
        /// 通过id查询学生信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public StudentEntity GetSudent(int id);

        /// <summary>
        /// 新增学生
        /// </summary>
        /// <param name="student"></param>
        /// <returns></returns>
        public int AddStudent(StudentEntity student);

        /// <summary>
        /// 修改学生
        /// </summary>
        /// <param name="student"></param>
        /// <returns></returns>
        public int UpdateStudent(StudentEntity student);

        /// <summary>
        /// 删除学生
        /// </summary>
        /// <param name="id"></param>
        public int DeleteStudent(int id);
    }
}

学生服务实现类StudentAppService

学生服务实现类是对接口的实现,如下所示:

namespace SIMS.WebApi.Services.Student
{
    public class StudentAppService : IStudentAppService
    {
        private DataContext dataContext;

        public StudentAppService(DataContext dataContext) {
            this.dataContext = dataContext;
        }

        /// <summary>
        /// 新增学生
        /// </summary>
        /// <param name="student"></param>
        /// <returns></returns>
        public int AddStudent(StudentEntity student)
        {
            var entry = dataContext.Students.Add(student);
            dataContext.SaveChanges();
            return 0;
        }

        /// <summary>
        /// 删除学生
        /// </summary>
        /// <param name="id"></param>
        public int DeleteStudent(int id)
        {
            var entity = dataContext.Students.FirstOrDefault(x => x.Id == id);
            if (entity != null)
            {
                dataContext.Students.Remove(entity);
                dataContext.SaveChanges();
            }
            return 0;
        }

        /// <summary>
        /// 查询学生列表
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageNum">页数</param>
        /// <param name="pageSize">每页大小</param>
        /// <returns></returns>
        public PagedRequest<StudentEntity> GetStudents(string no,string name,int pageNum,int pageSize)
        {
            IQueryable<StudentEntity> students = null;
            if (!string.IsNullOrEmpty(name) && string.IsNullOrEmpty(no))
            {
                students = dataContext.Students.Where(r => r.Name.Contains(name) && r.No.Contains(no)).OrderBy(r => r.Id);
            }
            else if (!string.IsNullOrEmpty(name))
            {
                students = dataContext.Students.Where(r => r.Name.Contains(name)).OrderBy(r => r.Id);
            }
            else if (!string.IsNullOrEmpty(name)) {
                students = dataContext.Students.Where(r => r.No.Contains(no)).OrderBy(r => r.Id);
            }
            else
            {
                students = dataContext.Students.Where(r => true).OrderBy(r => r.Id);
            }
            int count = students.Count();
            List<StudentEntity> items;
            if (pageSize > 0)
            {
                items = students.Skip((pageNum - 1) * pageSize).Take(pageSize).ToList();
            }
            else {
                items = students.ToList();
            }
            return new PagedRequest<StudentEntity>()
            {
                count = count,
                items = items
            };
        }

        /// <summary>
        /// 查询某一班级的学生列表
        /// </summary>
        /// <param name="classId"></param>
        /// <returns></returns>
        public PagedRequest<StudentEntity> GetStudentsByClasses(int classId)
        {
            IQueryable<StudentEntity> students = dataContext.Students.Where(r => r.ClassesId==classId).OrderBy(r => r.Id);
            int count = students.Count();
            var items = students.ToList();
            return new PagedRequest<StudentEntity>()
            {
                count = count,
                items = items
            };
        }

        /// <summary>
        /// 通过id查询学生信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public StudentEntity GetSudent(int id)
        {
            var entity = dataContext.Students.FirstOrDefault(r => r.Id == id);
            return entity;
        }

        /// <summary>
        /// 修改学生
        /// </summary>
        /// <param name="student"></param>
        /// <returns></returns>
        public int UpdateStudent(StudentEntity student)
        {
            dataContext.Students.Update(student);
            dataContext.SaveChanges();
            return 0;
        }
    }
}

班级服务接口IClassesAppService

班级服务接口是对班级表操作的封装,如下所示:

namespace SIMS.WebApi.Services.Classes
{
    public interface IClassesAppService
    {
        public PagedRequest<ClassesEntity> GetClassess(string dept, string grade, int pageNum, int pageSize);

        /// <summary>
        /// 通过id查询班级信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ClassesEntity GetClasses(int id);

        /// <summary>
        /// 新增班级
        /// </summary>
        /// <param name="classes"></param>
        /// <returns></returns>
        public int AddClasses(ClassesEntity classes);

        /// <summary>
        /// 修改班级
        /// </summary>
        /// <param name="classes"></param>
        /// <returns></returns>
        public int UpdateClasses(ClassesEntity classes);

        /// <summary>
        /// 删除班级
        /// </summary>
        /// <param name="id"></param>
        public int DeleteClasses(int id);
    }
}

班级服务实现类ClassesAppService,如下所示:

namespace SIMS.WebApi.Services.Classes
{
    public class ClassesAppService : IClassesAppService
    {
        private DataContext dataContext;

        public ClassesAppService(DataContext dataContext)
        {
            this.dataContext = dataContext;
        }

        /// <summary>
        /// 新增班级
        /// </summary>
        /// <param name="classes"></param>
        /// <returns></returns>
        public int AddClasses(ClassesEntity classes)
        {
            var entry = dataContext.Classes.Add(classes);
            dataContext.SaveChanges();
            return 0;
        }

        /// <summary>
        /// 删除班级
        /// </summary>
        /// <param name="id"></param>
        public int DeleteClasses(int id)
        {
            var entity = dataContext.Classes.FirstOrDefault(x => x.Id == id);
            if (entity != null)
            {
                dataContext.Classes.Remove(entity);
                dataContext.SaveChanges();
            }
            return 0;
        }

        /// <summary>
        /// 查询班级
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ClassesEntity GetClasses(int id)
        {
            var entity = dataContext.Classes.FirstOrDefault(r => r.Id == id);
            return entity;
        }

        public PagedRequest<ClassesEntity> GetClassess(string dept, string grade, int pageNum, int pageSize)
        {
            IQueryable<ClassesEntity> classes = null;
            if (!string.IsNullOrEmpty(dept) && string.IsNullOrEmpty(grade))
            {
                classes = dataContext.Classes.Where(r => r.Dept.Contains(dept) && r.Grade.Contains(grade)).OrderBy(r => r.Id);
            }
            else if (!string.IsNullOrEmpty(dept))
            {
                classes = dataContext.Classes.Where(r => r.Dept.Contains(dept)).OrderBy(r => r.Id);
            }
            else if (!string.IsNullOrEmpty(grade))
            {
                classes = dataContext.Classes.Where(r => r.Grade.Contains(grade)).OrderBy(r => r.Id);
            }
            else
            {
                classes = dataContext.Classes.Where(r => true).OrderBy(r => r.Id);
            }
            int count = classes.Count();
            List<ClassesEntity> items=new List<ClassesEntity>();
            if (pageSize < 1)
            {
                items = classes.ToList();
            }
            else {
               items = classes.Skip((pageNum - 1) * pageSize).Take(pageSize).ToList();
            }

            return new PagedRequest<ClassesEntity>()
            {
                count = count,
                items = items
            };
        }

        /// <summary>
        /// 修改班级
        /// </summary>
        /// <param name="classes"></param>
        /// <returns></returns>
        public int UpdateClasses(ClassesEntity classes)
        {
            dataContext.Classes.Update(classes);
            dataContext.SaveChanges();
            return 0;
        }
    }
}

其他服务接口和类尚不完善,暂时先不贴代码。

3. 创建控制器

接口控制器就是客户端访问的入口,与接口服务对应,一个四个接口控制器,如下所示:

学生控制器StudentController

学生控制器封装学生操作的服务,包括学生的增删改查的接口,如下所示:

namespace SIMS.WebApi.Controllers
{
    /// <summary>
    /// 学生控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class StudentController : ControllerBase
    {
        private readonly ILogger<StudentController> logger;

        private readonly IStudentAppService studentAppService;

        public StudentController(ILogger<StudentController> logger, IStudentAppService studentAppService) {
            this.logger = logger;
            this.studentAppService = studentAppService;
        }

        /// <summary>
        /// 学生列表,带分页
        /// </summary>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <param name="no"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [HttpGet]
        public PagedRequest<StudentEntity> GetStudents(int pageNum, int pageSize,string? no = null ,string? name=null ) {
            return studentAppService.GetStudents(no,name, pageNum, pageSize);
        }

        /// <summary>
        /// 查询某一班级的学生列表
        /// </summary>
        /// <param name="classId"></param>
        /// <returns></returns>
        [HttpGet]
        public PagedRequest<StudentEntity> GetStudentsByClasses(int classId) {
            return studentAppService.GetStudentsByClasses(classId);
        }

        /// <summary>
        /// 获取学生信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public StudentEntity GetStudent(int id) {
            return studentAppService.GetSudent(id);
        }

        /// <summary>
        /// 新增学生
        /// </summary>
        /// <param name="student"></param>
        /// <returns></returns>
        [HttpPost]
        public int AddStudent(StudentEntity student)
        {
            return studentAppService.AddStudent(student);
        }

        /// <summary>
        /// 修改学生
        /// </summary>
        /// <param name="student"></param>
        /// <returns></returns>
        [HttpPut]
        public int UpdateStudent(StudentEntity student) {
            return studentAppService.UpdateStudent(student);
        }

        /// <summary>
        /// 删除学生
        /// </summary>
        /// <param name="id"></param>
        [HttpDelete]
        public int DeleteStudent(int id)
        {
            return studentAppService.DeleteStudent(id);
        }
    }
}

班级控制器ClassesController

班级控制器是对班级接口服务的封装,包含对班级的增删改查,如下所示:

namespace SIMS.WebApi.Controllers
{
    /// <summary>
    /// 班级控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class ClassesController : ControllerBase
    {
        private readonly ILogger<ClassesController> logger;

        private readonly IClassesAppService classesAppService;

        public ClassesController(ILogger<ClassesController> logger, IClassesAppService classesAppService)
        {
            this.logger = logger;
            this.classesAppService = classesAppService;
        }

        /// <summary>
        /// 获取班级信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public ClassesEntity GetClasses(int id)
        {
            return classesAppService.GetClasses(id);
        }

        /// <summary>
        /// 获取班级列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public PagedRequest<ClassesEntity> GetClassess(string? dept, string? grade, int pageNum, int pageSize)
        {
            return classesAppService.GetClassess(dept,grade,pageNum,pageSize);
        }

        /// <summary>
        /// 新增班级
        /// </summary>
        /// <param name="classes"></param>
        /// <returns></returns>
        [HttpPost]
        public int AddClasses(ClassesEntity classes)
        {
            return classesAppService.AddClasses(classes);
        }

        /// <summary>
        /// 修改班级
        /// </summary>
        /// <param name="classes"></param>
        /// <returns></returns>
        [HttpPut]
        public int UpdateClasses(ClassesEntity classes)
        {
            return classesAppService.UpdateClasses(classes);
        }

        /// <summary>
        /// 删除班级
        /// </summary>
        /// <param name="id"></param>
        [HttpDelete]
        public int DeleteClasses(int id)
        {
            return classesAppService.DeleteClasses(id);
        }
    }
}

注意:其他控制器,暂是代码不全,暂不贴示。

通过以上示例可以看出,接口服务依赖DataContext,控制器依赖接口服务,那么如果要使程序得以运行,就要逐层创建对象,并传递对象实体。手工创建非常不方便,所以就需要引入Autofac进行自动注入,如下所示:

4. 注入DataContext

在Program中,通过构造器,注入DataContext,如下所示:

builder.Services.AddDbContext<DataContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

注意:Default为appsetting.json中配置的数据库连接字符串。如下所示:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "Default": "Server=localhost;Database=SIMS;Trusted_Connection=True;User Id=sa;Password=abc123"
  },
  "AllowedHosts": "*"
}

5. 配置Autofac框架

Autoface框架可以实现接口的自动注入,减少繁琐的人工操作,如下所示:

// 以下是autofac依赖注入
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{   // 注入Service程序集
    string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
    builder.RegisterAssemblyTypes(Assembly.Load(assemblyName))
    .AsImplementedInterfaces()
    .InstancePerDependency();
});

Program中全部代码,如下所示:

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using SIMS.WebApi;
using SIMS.WebApi.Data;
using SIMS.WebApi.Services.Student;
using System.Configuration;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<DataContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));
// 以下是autofac依赖注入
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{   // 注入Service程序集
    string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
    builder.RegisterAssemblyTypes(Assembly.Load(assemblyName))
    .AsImplementedInterfaces()
    .InstancePerDependency();
});
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

6. 代码结构

WebApi中代码结构如下所示:

 

7. 运行WebApi服务

经过以上步骤的操作,Api接口已经基本搭建完成,将SIMS.WebApi作为启动项目,运行VS,如下所示:

8. 接口测试

默认情况下WebApi继承了Swagger,可以进行简单的测试,以/api/Classes/GetClasses为例,输入班级ID,就可查询班级信息,如下所示:

 以上就是本次的主要内容,包含数据库的基本操作和WebApi接口的创建流程,旨在抛转引玉,一起学习,共同进步。

备注

上邪【作者】佚名 【朝代】汉

上邪,我欲与君相知,长命无绝衰。

山无陵,江水为竭。

冬雷震震,夏雨雪。

天地合,乃敢与君绝。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: WPF是一种基于XAML语言的用户界面开发框架,使开发人员能够轻松创建漂亮和高效的桌面应用程序。MVVM是一种模式,它在WPF应用程序中广泛使用,它提供了一种分离UI和业务逻辑的方式,从而简化了代码结构。Prism是一个开源框架,它基于MVVM模式和WPF框架,提供了一些技术和工具,使开发人员能够更轻松地构建复杂的WPF应用程序。 使用WPF MVVM Prism框架可以帮助开发人员提高应用程序的可维护性和可扩展性。通过MVVM,开发人员可以创建一个适应各种应用程序场景的模型,并将其与UI分离。数据绑定和命令绑定使开发人员能够更轻松地将模型中的数据和逻辑与UI控件集成起来。Prism框架还提供了一些工具和功能,如模块化应用程序开发、事件聚合器、导航、对话框、异常处理等功能。这些工具使开发人员能够更轻松地构建复杂的应用程序,并提供了一种可扩展和可重用的方法。 总之,使用WPF MVVM Prism可以使开发人员更轻松地构建复杂的应用程序,并提高应用程序的可维护性和可扩展性。开发人员可以根据自己的需求选择使用这个框架来开发WPF应用程序,从而提高他们的工作效率和代码质量。 ### 回答2: WPF MVVM Prism是一种基于Windows Presentation Foundation(WPF)的软件开发模式,采用了MVVM(Model-View-ViewModel)设计模式和Prism框架来实现软件开发。MVVM是一种在WPF应用程序中使用的设计模式,它将应用程序的视图(View)与应用程序的模型(Model)分离开来,通过ViewModel来连接者。Prism是一个帮助开发人员编写出复杂、可管控、可扩展和可维护的WPF应用程序的框架。 WPF MVVM Prism提供了很多好处:首先,它能实现软件的可重用性,通过将代码和视图分离,使得代码可以在多个不同的视图中重复使用,提高了开发效率。其次,它可以提高软件的可维护性,通过将逻辑和视图分离,确保逻辑代码与UI代码之间更少的耦合,提高了软件的可扩展性。此外,它还可以提高软件的可测试性,由于MVVM模式中将视图和逻辑分离开,所以开发人员可以更容易地编写出单元测试代码,来测试逻辑代码。最后,由于Prism框架提供了一些通用的,可定制的模块和服务,使得开发人员可以更快地实现常见功能、缩短开发时间。 总之,WPF MVVM Prism是一种高效、可扩展和易于维护的软件开发模式,它将视图和逻辑分离,提高了软件的可重用性和可测试性,同时也提高了软件的可扩展性和可复用性。 ### 回答3: WPF是一种桌面应用程序框架,它允许您为Windows创建高度交互式和可视化的应用程序界面。MVVM是一种软件编程模式,它将用户界面(UI)与业务逻辑分离,以便更好地实现可维护,可扩展和可组合的代码。Prism是一个WPF和Silverlight应用程序的组件库,它提供了一些可重用和可扩展的基础设施组件,帮助您更快速地构建、测试和维护WPF应用程序。因此,WPF MVVM Prism的组合可以帮助您更轻松高效地开发WPF应用程序。您可以使用MVVM模式来改进应用程序的结构和测试,使用Prism来更好地组织和可扩展您的代码,以及使用WPF来实现交互丰富的UI。同时还可以使用Prism提供的事件聚合器、导航器和模块化架构,实现更灵活的应用程序设计。WPF MVVM Prism的组合提供了一种更有效的方式来构建WPF应用程序,以满足现代用户体验的需求,并且更容易测试和维护,因此它已成为WPF应用程序开发的重要组合。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老码识途呀

写作不易,多谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值