前言:
本章主要通过一个完整的示例讲解ASP.NET Core MVC+EF Core对MySQL数据库进行简单的CRUD操作,希望能够为刚入门.NET Core的小伙伴们提供一个完整的参考实例。关于ASP.NET Core MVC+EF操作MsSQL Server详情请参考官方文档(https://docs.microsoft.com/zh-cn/aspnet/core/data/ef-mvc/?view=aspnetcore-3.1)。
示例实现功能预览:
博客实例源码下载地址:
https://github.com/YSGStudyHards/ASP.NET-Core-MVC-Layui-EF-Core-CRUD_Sample
一、创建ASP.NET Core Web应用程序:
注意,本章节主要以APS.NET Core 3.1版本作为博客的样式实例!
二、添加EF Core NuGet包:
若要在项目中使用EF Core操作MySQL数据库,需要安装相应的数据库驱动包。本章教程主要使用 MySQL数据库,所以我们需要安装相关驱动包MySql.Data.EntityFrameworkCore。
安装方式:
点击工具=>NuGet包管理器=>程序包管理器控制台输入以下命令:
Install-Package MySql.Data.EntityFrameworkCore -Version 8.0.20
点击工具=>NuGet包管理器=>管理解决方案的NuGet程序包:
搜索:MySql.Data.EntityFrameworkCore 点击安装。
三、创建对应数据库表的实体模型:
注意该篇博客使用的是手动模型优先的方式进行数据库表字段与模型属性映射,当然如果大家觉得这样子比较麻烦的话可以真正意义上的模型优先,直接创建模型在program.cs中配置创建对应模型的数据库逻辑代码即可无需手动创建数据库,可参考官网文档教程(https://docs.microsoft.com/zh-cn/aspnet/core/data/ef-rp/intro?view=aspnetcore-3.1&tabs=visual-studio#create-the-database)。
创建用户模型(UserInfo):
注意:属性大小写和数据库中的表字段保持一致,Id
属性成为此类对应的数据库表的主键列。 默认情况下,EF Core 将名为 Id
或 xxxID
的属性视为主键。有关详细信息,请参阅密钥-EF Core | Microsoft Docs。
/// <summary> /// 学生信息模型 /// </summary> public class UserInfo { /// <summary> /// 学生编号 /// </summary> [Description("学生编号")] public int? Id { get; set; } /// <summary> /// 学生姓名 /// </summary> [Description("学生姓名")] public string UserName { get; set; } /// <summary> /// 学生性别 /// </summary> [Description("学生性别")] public string Sex { get; set; } /// <summary> /// 学生联系电话 /// </summary> [Description("学生联系电话")] public string Phone { get; set; } /// <summary> /// 学生描述 /// </summary> [Description("学生描述")] public string Description { get; set; } /// <summary> /// 学生爱好 /// </summary> [Description("学生爱好")] public string Hobby { get; set; } }
四、将数据库连接字符串添加到 appsettings.json:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "ConnectionStrings": { "MySqlConnection":"Data Source=127.0.0.1;User ID=root;Password=root;DataBase=SchoolUserInfo_db" } }
五、创建数据库上下文:
概述:
数据库上下文类是为给定数据模型协调 EF Core 功能的主类。 上下文派生自 Microsoft.EntityFrameworkCore.DbContext。 上下文指定数据模型中包含哪些实体。 在此项目中将数据库上下文类命名为 SchoolUserInfoContext。
创建:
using Microsoft.EntityFrameworkCore; using Model; namespace Dal { public class SchoolUserInfoContext : DbContext { public SchoolUserInfoContext(DbContextOptions<SchoolUserInfoContext> options) : base(options) { } /// <summary> /// DbSet实体集属性对应数据库中的表(注意实体集名必须与表明一致) /// </summary> public DbSet<UserInfo> UserInfos { get; set; } /// <summary> /// TODO:当数据库创建完成后, EF 创建一系列数据表,表名默认和 DbSet 属性名相同。 集合属性的名称一般使用复数形式,但不同的开发人员的命名习惯可能不一样, /// 开发人员根据自己的情况确定是否使用复数形式。 在定义 DbSet 属性的代码之后,添加下面代码,对DbContext指定单数的表名来覆盖默认的表名。 /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<UserInfo>().ToTable("UserInfo"); } } }
六、将上下文添加到 Startup.cs 中的依赖项注入:
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //注入EF Core数据库上下文服务 services.AddDbContext<SchoolUserInfoContext>(options => options.UseMySQL(Configuration.GetConnectionString("MySqlConnection"))); services.AddControllersWithViews(); }
七、引入Layui样式和js:
前往官网下载Layui相关样式和js包,下载地址:https://www.layui.com/
Layui弹出层插件layer.js(有很多地方需要用到弹窗),下载地址:https://layer.layui.com/
将相关文件存放到wwwroot文件下:
将相关文件引入默认布局页面中:
八、 ASP.NET Core MVC 和 EF Core实现MySQL CRUD功能:
注意在这里主要展示的EF Core与数据库操作的部分代码,详细代码可下载实例源码查看。
Create:
/// <summary> /// 学生信息添加 /// </summary> /// <param name="addUserInfo"></param> /// <returns></returns> public async Task<bool> Create(AddUserInfoViewModel addUserInfo) { try { var userInfo=new UserInfo() { UserName = addUserInfo.UserName, Sex = addUserInfo.Sex, Hobby = addUserInfo.Hobby, Phone = addUserInfo.Phone, Description = addUserInfo.Description }; _shoSchoolUserInfoContext.UserInfos.Add(userInfo); await _shoSchoolUserInfoContext.SaveChangesAsync(); return true; } catch { return false; } }
Retrieve:
/// <summary> /// 获取用户信息 /// </summary> /// <param name="page">当前页码</param> /// <param name="limit">显示条数</param> /// <param name="userName">用户姓名</param> /// <returns></returns> public async Task<PageSearchModel> GetPageListData(int page = 1, int limit = 15, string userName = "") { try { List<UserInfo> listData; var totalCount = 0; if (!string.IsNullOrWhiteSpace(userName)) { listData = await _shoSchoolUserInfoContext.UserInfos.Where(x => x.UserName.Contains(userName)).OrderByDescending(x => x.Id).Skip((page - 1) * limit).Take(limit).ToListAsync(); totalCount = _shoSchoolUserInfoContext.UserInfos .Count(x => x.UserName.Contains(userName)); } else { listData = await _shoSchoolUserInfoContext.UserInfos.OrderByDescending(x => x.Id).Skip((page - 1) * limit).Take(limit).ToListAsync(); totalCount = _shoSchoolUserInfoContext.UserInfos.Count(); } return new PageSearchModel() { ResultMsg = "success", Code = 200, TotalCount = totalCount, DataList = listData }; } catch (Exception e) { return new PageSearchModel() { Code = 400, ResultMsg = e.Message }; } }
Update:
/// <summary> /// 学生信息修改 /// </summary> /// <param name="userInfo"></param> /// <returns></returns> public async Task<bool> Update(UserInfo userInfo) { try { _shoSchoolUserInfoContext.UserInfos.Update(userInfo); await _shoSchoolUserInfoContext.SaveChangesAsync(); return true; } catch { return false; } }
Delete:
/// <summary> /// 学生信息删除 /// </summary> /// <param name="id"></param> /// <returns></returns> public async Task<bool> Delete(int? id) { try { var searchUserInfo = await _shoSchoolUserInfoContext.UserInfos.FindAsync(id); if (searchUserInfo == null) { return false; } _shoSchoolUserInfoContext.UserInfos.Remove(searchUserInfo); await _shoSchoolUserInfoContext.SaveChangesAsync(); return true; } catch { return false; } }