目录

声明:该项目用的是3.1版本

新建项目

新创建项目之间的依赖关系如下:

配置DbContext使用依赖注入

实现登录

账号密码验证

1、Model层

2、Service层

3、Controller层,Startup类添加依赖注入

cookie验证登录

JWT验证

登录跳转页面

跳转大致思路:

登录成功跳转验证:

退出登录操作

退出大致思路:

页面数据渲染

渲染大致思路:

编写数据接口

大致思路:

实现数据渲染效果:

链接多表渲染数据

Join连接

Join链接三张表

Linq连接

实现分页

增删改查

查询

删除

实现批量删除

增加数据

实现添加功能

更改数据

结尾


创建项目,引入EF框架

声明:该项目用的是3.1版本

新建项目

创建三层,在项目里面再新建三个类库

最终效果:

新创建项目之间的依赖关系如下:

Service层:业务处理层,(里面有接口和实现类)

Model层:模型层(将需要的数据进行封装,给Service层进行数据逻辑处理)

Controller层:控制层(调用Service层封装的方法)

DataDepository层:将数据库的表存储在项目里,

需要先下载EF程序包

需要的三个包效果:

生成数据库Model之前要将此程序设置为启动项目

选项工具打开控制台

将我们的 DataDepository层设置为启动项目

接着在控制台输入这段代码(注意修改自己的用户名密码以及要连接的数据库名):Scaffold-DbContext "Data Source=.;Initial Catalog=Hospital;User ID=sa;Password=root" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

说明成功  完成展示:


配置DbContext使用依赖注入

什么是依赖注入?这些专业名词解释起来会比较麻烦,介绍起来会比较繁琐,推荐百度去弄清楚逻辑,后面会经常用到依赖注入,不弄清楚可能会对后面的步骤造成影响,建议先去弄清楚概念

appsettings.json,

注意更改自己要连接的数据库账号密码

"ConnectionStrings": {
    "HospitalConnnStr": "Data Source=.;Initial Catalog=Hospital;User ID=sa;Password=123456"
  }

Startup.cs

//数据库的依赖注入
            var constr = Configuration.GetConnectionString("HospitalConnnStr");
            services.AddDbContext<HospitalContext>(opt =>
            {
                opt.UseSqlServer(constr);
            });

添加注入后,运行测试看是否有误:

可以运行,就说明没有错误,出现这个也不用担心,正常现象

实现登录

Service层:业务处理层,(里面有接口和实现类)
Model层:模型层(将需要的数据进行封装,给Service层进行数据逻辑处理)
Controller层:控制层(调用Service层封装的方法)
DataDepository层:将数据库的表存储在项目里,

后面的操作大部分都是先Model层(将需要的数据从DataDepository层获取)-->Service层(从Model层获取到需要的值进行逻辑代码编写)-->Controller层(调用Service层方法形成接口)

Controller层添加UserController控制器,用来实现账号密码登录的前端界面

接着在UserController的index方法添加视图行页面编写样式

 

添加好视图之后,就要添加Layui的布局,这样我们就可以使用Layui的样式进行前端布局

添加Layout布局同样是在Controller层进行操作

_Layout.cshtml的页面添加上Layout的css和js样式,官网Layui 开发使用文档 - 入门指南

将这两段放入页面中

  1. <!-- 引入 layui.css -->
  2. <link rel="stylesheet" href="//unpkg.com/layui@2.6.8/dist/css/layui.css">
  3. <!-- 引入 layui.js -->
  4. <script src="//unpkg.com/layui@2.6.8/dist/layui.js">

效果:

注意:引入JS的时候,注意补全

然后添加前端布局在刚刚创建的index视图里面,创建的视图在View文件夹里面的User包下,User包就是我们所创建的控制台省去了Controller的后缀

添加前端样式

<form class="layui-form" action=""><div class="layui-form-item"><label class="layui-form-label">输入框</label><div class="layui-input-block"><input type="text" name="username" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item"><label class="layui-form-label">密码框</label><div class="layui-input-block"><input type="password" name="pwd" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item"><div class="layui-input-block"><button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button><button type="reset" class="layui-btn layui-btn-primary">重置</button></div></div>
</form><script>//Demo:提交登录window.onload = function () {layui.use('form', function () {var form = layui.form;//监听提交form.on('submit(formDemo)', function (data) {// layer.msg(JSON.stringify(data.field));$.post("/user/login2", data.field, function (res) {if (res == "success") {layer.msg("恭喜您,登录成功");//location.href = "/main/index";} else {layer.msg("登录失败,请检查用户名和密码是否正确");}});return false;});});}</script>

5、接口测试:

账号密码验证

刚刚我们只是实现了登录的一个界面,提交之后总是失败,是因为我们还没有实现登录的验证

1、Model层

Model层:模型层(将需要的数据进行封装,这个数据是来自DataDepository数据层,然后给Service层进行数据逻辑处理)

创建一个UserModel类,在登录的时候验证用户和密码是否在数据库里,这里的属性要与DataDepositoryDoctor类属性的一样

public class UserModel{public string UserName { get; set; }public string pwd { get; set; }}

2、Service层

Service层:业务处理层,(里面有接口和实现类)

先创建接口和实现类(IUserServiceUserService)

效果:

实现步骤:

 注意一个是接口,一个是类

注意:在接口和类都要加上一个public:访问权限修饰符,表示被修饰者有公共访问权限

接口(IUserService):

IUserService接口创建一个方法

或者手动生成(但是推荐使用快捷键,后面会经常用到)

IUserService效果:

注意:  现在接口声明的方法中有两个参数-->usernamepwd,分别代表用户名和密码,这两个参数的名字要和我们在controller层声明的index视图的参数要一样

继承接口类(UserService):

类需要继承接口:冒号“  ”代表继承

而且需要实现接口的方法(这样是为了方便后面的修改,因为接口是可以多个类去继承并实现不同的业务逻辑,这样如果后续需要修改就只用找到我们想要修改的类直接去修改,如果修改接口,那么继承该接口的实现类也要去修改业务逻辑,会增加工作量)

实现接口方法快捷键Alt+回车键,快捷键在后面不多介绍,记住快捷键,有利于开发效率

效果:

此外,我们还需要添加一些属性

接着需要新建一个有参构造器,把我们刚刚声明的属性放在构造器里面

为什么要新建一个构造函数呢?解释起来会比较啰嗦,就不介绍了,目前就只用明白,只要添加了属性,而且要使用该属性就要重新定义一个有参的构造函数,想要更加了解有参和无参构造器,可以百度查查。

 效果:

最后需要对方法进行逻辑代码编写:

public Doctor Login2(string username, string pwd, JwtOpt jwtOpt){if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(pwd)){return null;}//FirstOrDefault:如果有数据那么只取第一条,如果没有返回数据那么就返回nullvar doctor = _hospitalContext.Doctors.Where(doct => doct.UserName == username&& doct.Password == pwd).FirstOrDefault();//如果为null,表示用户不存在,那么就登录失败return doctor;}

3、Controller层,Startup类添加依赖注入

Controller层:控制层(调用Service层封装的方法)

先依赖注入:在Controller层的启动类Startup.cs类中配置

创建UserController控制器

Controller层实现Service层方法,形成接口

接口测试:接口不区分答案小写

因为这里我们还没有进行登录,所有验证的时候返回的值是fail

进行登录验证

cookie验证登录

1、添加cookie验证(在startup.cs文件里添加cookie验证服务),路径根据自己设置的登录接口去更改

//使用cookie登录services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(option =>{option.LoginPath = "/user/login";option.AccessDeniedPath = "/user/login";});

效果

2、接着在startup.cs加入中间件,先后顺序不能弄错

//身份验证,用来解析、验证tokenapp.UseAuthentication();//授予权限,权限的判断app.UseAuthorization();

效果

3、在Controller层在我们调用登录方法中加入cookie验证

public async Task<string> Login2(UserModel userModel){var doctor = _userService.Login2(userModel.UserName, userModel.pwd);if (doctor == null){return "fail";}//生成cokenvar claims = new[]{//Dictionary<string,string>new Claim(ClaimTypes.Name,doctor.UserName),new Claim("userid",doctor.DId.ToString()),new Claim(ClaimTypes.Role,"admin")};ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme));//生成cookieawait HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);return "success";}

效果

4、最终效果,登录后生成cookie代表成功

JWT验证

1、在Controller层的项目下安装JWT

2、在appsettings.json配置类设置

 "JwtOpt": {"Audience": "https://localhost:44359","Issuer": "https://localhost:44359","SecurityKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"}

3、Model层新建类JwtOpt.cs用以映射返回给前端,前面我们也建立了一个UserModel,但这里新建的作用是将我们从后端获得的数据用前端的方式返回给前端

注意:不能有错,属性不能有错

public string Audience { get; set; }
public string Issuer { get; set; }
public string SecurityKey { get; set; }

然后将JwtOpt.cs添加到我们的Serivice层的IUserService接口中

接口改变了,对应的实现类也要进行更改

与之逻辑相同,Service层的代码发生更改,那么Controller调用Service层的方法也要进行一个修改

4、在controller层的启动类(Startup.cs)配置,每次新建的一个类,而且在使用之前,都要先进行依赖注入,牢记

进行注入:

报红是没有引入,使用快捷键Alt+回车键快速引入

//验证的方式(配置为jwt):JwtBearerDefaults.AuthenticationScheme//配置怎么去验证token以及谁来验证tokenservices.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{var jwtOpt = Configuration.GetSection("JwtOpt").Get<JwtOpt>();options.RequireHttpsMetadata = false;options.SaveToken = true;options.TokenValidationParameters = new TokenValidationParameters{ValidateIssuer = false,//是否验证颁发者ValidateAudience = false,//是否验证客户端ValidateLifetime = true,//验证token的有效期ClockSkew = TimeSpan.FromSeconds(10),//验证过期时间有一点偏差ValidateIssuerSigningKey = true,//验证签名ValidIssuer = jwtOpt.Issuer,   //配置颁发者ValidAudience = jwtOpt.Audience,  //配置客户端//配置加密的keyIssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOpt.SecurityKey))};});

还要进行一个全局配置,也是在注入的地方Startup类进行添加

  services.AddControllersWithViews().AddJsonOptions(options =>{//解决中文输出后被编码了,设置支持所有字符集options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);}).AddMvcOptions(opt =>{//全局配置必须登录才能访问整个网站的所有接口opt.Filters.Add(new AuthorizeFilter());});

然后进行接口测试,看我们是否添加上了jwt的验证

进行测试:

发现我们现在不论是什么接口的页面都无法进行访问,而且还出现了401的接口访问权限,说明我们的接口访问是正确的,只是开启了jwt验证而没有权限进行访问

5、解决jwt权限的认证,

我们只用在Controller层找到对我们的控制器编译器加上一个注解就能解决了401的接口权限问题

[AllowAnonymous]

表示允许访问该方法

效果:

登录跳转页面

跳转大致思路:

先加入一个需要页面-->Controller层编写接口跳转到页面-->最后使用跳转路径到指定页面

需要整入后台框架样板布局,效果如下:

先在公共页面复制粘贴_Layout1.cshtml页面为_Layout2.cshtml,(当然可以自己随意取,但要方便辨认)用于跳转到框架布局,页面内容就是框架的布局

如果想导入自己下载的JS和CSS文件,需要将下载的文件存放到wwwroot文件夹下面,但是推荐直接使用官网路径,因为自己下载的可能会造成一些样式的缺失

接着去官网获取样式布局,网址:Layui 管理界面大框架布局 - 在线演示

对了,添加上布局,别忘了把官网的cssjs布局引入进去

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><title>layout 管理系统大布局 - Layui</title>@*<link rel="stylesheet" href="./layui/css/layui.css">*@<link href="https://cdn.staticfile.org/layui/2.7.6/css/layui.css" rel="stylesheet">
</head>
<body><div class="layui-layout layui-layout-admin"><div class="layui-header"><div class="layui-logo layui-hide-xs layui-bg-black">layout demo</div><!-- 头部区域(可配合layui 已有的水平导航) --><ul class="layui-nav layui-layout-left"><!-- 移动端显示 --><li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft"><i class="layui-icon layui-icon-spread-left"></i></li><li class="layui-nav-item layui-hide-xs"><a href="">nav 1</a></li><li class="layui-nav-item layui-hide-xs"><a href="">nav 2</a></li><li class="layui-nav-item layui-hide-xs"><a href="">nav 3</a></li><li class="layui-nav-item"><a href="javascript:;">nav groups</a><dl class="layui-nav-child"><dd><a href="">menu 11</a></dd><dd><a href="">menu 22</a></dd><dd><a href="">menu 33</a></dd></dl></li></ul><ul class="layui-nav layui-layout-right"><li class="layui-nav-item layui-hide layui-show-md-inline-block"><a href="javascript:;"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">tester</a><dl class="layui-nav-child"><dd><a href="">Your Profile</a></dd><dd><a href="">Settings</a></dd><dd><a href="">Sign out</a></dd></dl></li><li class="layui-nav-item" lay-header-event="menuRight" lay-unselect><a href="javascript:;"><i class="layui-icon layui-icon-more-vertical"></i></a></li></ul></div><div class="layui-side layui-bg-black"><div class="layui-side-scroll"><!-- 左侧导航区域(可配合layui已有的垂直导航) --><ul class="layui-nav layui-nav-tree" lay-filter="test"><li class="layui-nav-item layui-nav-itemed"><a class="" href="javascript:;">menu group 1</a><dl class="layui-nav-child"><dd><a href="javascript:;">menu 1</a></dd><dd><a href="javascript:;">menu 2</a></dd><dd><a href="javascript:;">menu 3</a></dd><dd><a href="">the links</a></dd></dl></li><li class="layui-nav-item"><a href="javascript:;">menu group 2</a><dl class="layui-nav-child"><dd><a href="javascript:;">list 1</a></dd><dd><a href="javascript:;">list 2</a></dd><dd><a href="">超链接</a></dd></dl></li><li class="layui-nav-item"><a href="javascript:;">click menu item</a></li><li class="layui-nav-item"><a href="">the links</a></li></ul></div></div><div class="layui-body"><!-- 内容主体区域 --><div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div></div><div class="layui-footer"><!-- 底部固定区域 -->底部固定区域</div></div>@*<script src="./layui/layui.js"></script>*@<script src="https://cdn.staticfile.org/layui/2.7.6/layui.js"></script><script>//JSlayui.use(['element', 'layer', 'util'], function () {var element = layui.element, layer = layui.layer, util = layui.util, $ = layui.$;//头部事件util.event('lay-header-event', {//左侧菜单事件menuLeft: function (othis) {layer.msg('展开左侧菜单的操作', { icon: 0 });}, menuRight: function () {layer.open({type: 1, content: '<div style="padding: 15px;">处理右侧面板的操作</div>', area: ['260px', '100%'], offset: 'rt' //右上角, anim: 5, shadeClose: true});}});});</script>
</body>
</html>

为了验证我们是否成功添加上了布局我们还需要在Controller层新建一个控制器命名为MainController,用来我们的后台样式布局首页面,在Main视图里添加一个新的视图文件,同时也用于登录成功之后跳转到我们的后台管理页面

提示:在实现登录里对视图,控制器,接口和类等添加 方面都有比较详细的介绍,到后面就会比较直接快速的建立类以此来避免不必要的重复,如在后面对这些添加类等比较模糊,可以看看实现登录的部分

添加视图效果:

将Main构造器里的index视图数据绑定到前面创造的 _Layout2.cshtml页面下

在视图里加了一个h1标签,是为了验证是否是main里的index视图

别忘了我们前面加入了jwt验证,需要加上可访问的注解在Controller层的方法上

[AllowAnonymous]

现在就能进行接口的访问

访问main/index接口出现了问题,报错原因提示我们index的页面没有渲染到我们指定的页面上

解决方法:

在我们要跳转的页面即/Views/Shared/_Layout2.cshtml页面上添加一个@RenderBody注解

解释:@RenderBody是一个占位符,是留给子页面的位置,子页面使用这个模版,子页面中的内容会被放到@RenderBody的位置。合并后当作一个整体加载。

不过还要注意添加的位置,不要弄错了

再次进行接口访问:

成功

为了方便,我们更改调试的默认页面为登录页面,利于开发效率,根据自己的控制器的名称和方法去修改

修改:

同样是不区别大小写的

最后在登录页面,登录成功之后进行成功路径的跳转

location.href = "/main/index";
//路径根据自己的接口去修改,后面也是一样不会过多的重复

登录成功跳转验证:

提交登录之后确实跳转到了我们指定的路径页面

退出登录操作

退出大致思路:

编写一个方法进行路径跳转到登录页面-->登录成功后调用接口跳转页面

我们在UserController控制层新增一个退出方法LoginOut

对方法编辑 :

HttpContext.SignOutAsync();
return Redirect("/user/index");//路径根据自己编写的去更改

jwt权限认证也别忘记添加

最后在_Layout2.cshtml页面进行路径的跳转,达到退出登录效果

退出登录测试:

点击之后就退出到了我们的登录验证页面就代表完成了退出登录操作

页面数据渲染

渲染大致思路:

在Main控制器的index视图中进行页面布局-->编写接口获取到数据库的表数据-->对页面布局将数据渲染在视图中

先进行页面布局,网址:在线示例 - Layui

@{Layout = "~/Views/Shared/_Layout2.cshtml";
}
<h1>我是main里的index视图</h1><table class="layui-hide" id="demo" lay-filter="test"></table><script type="text/html" id="barDemo"><a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">查看</a><a class="layui-btn layui-btn-xs" lay-event="more">更多 <i class="layui-icon layui-icon-down"></i></a>
</script><script>layui.config({version: '1632428048355' //为了更新 js 缓存,可忽略
});//加载模块
layui.use(function(){ //亦可加载特定模块:layui.use(['layer', 'laydate', function(){//得到各种内置组件var layer = layui.layer //弹层,laypage = layui.laypage //分页,laydate = layui.laydate //日期,table = layui.table //表格,carousel = layui.carousel //轮播,upload = layui.upload //上传,element = layui.element //元素操作,slider = layui.slider //滑块,dropdown = layui.dropdown //下拉菜单//向世界问个好layer.msg('Hello World');//监听Tab切换element.on('tab(demo)', function(data){layer.tips('切换了 '+ data.index +':'+ this.innerHTML, this, {tips: 1});});//执行一个 table 实例table.render({elem: '#demo',height: 420,url: '/demo/table/user/' //数据接口,url: '../demo/table/user/-page=1&limit=20.js' //数据接口,title: '用户表',page: true //开启分页,toolbar: 'default' //开启工具栏,此处显示默认图标,可以自定义模板,详见文档,totalRow: true //开启合计行,cols: [[ //表头{type: 'checkbox', fixed: 'left'},{field: 'id', title: 'ID', width:80, sort: true, fixed: 'left', totalRowText: '合计:'},{field: 'username', title: '用户名', width:80},{field: 'experience', title: '积分', width: 90, sort: true, totalRow: true},{field: 'sex', title: '性别', width:80, sort: true},{field: 'score', title: '评分', width: 80, sort: true, totalRow: '{{ parseInt(d.TOTAL_NUMS) }} 分'},{field: 'city', title: '城市', width:150} ,{field: 'sign', title: '签名', width: 200},{field: 'classify', title: '职业', width: 100},{field: 'wealth', title: '财富', width: 135, sort: true, totalRow: true},{fixed: 'right', width: 150, align:'center', toolbar: '#barDemo'}]]});//监听头工具栏事件table.on('toolbar(test)', function(obj){var checkStatus = table.checkStatus(obj.config.id),data = checkStatus.data; //获取选中的数据switch(obj.event){case 'add':layer.msg('添加');break;case 'update':if(data.length === 0){layer.msg('请选择一行');} else if(data.length > 1){layer.msg('只能同时编辑一个');} else {layer.alert('编辑 [id]:'+ checkStatus.data[0].id);}break;case 'delete':if(data.length === 0){layer.msg('请选择一行');} else {layer.msg('删除');}break;};});//监听行工具事件table.on('tool(test)', function(obj){ //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值"var data = obj.data //获得当前行数据,layEvent = obj.event; //获得 lay-event 对应的值if(layEvent === 'detail'){layer.msg('查看操作');} else if(layEvent === 'more'){//下拉菜单dropdown.render({elem: this //触发事件的 DOM 对象,show: true //外部事件触发即显示,data: [{title: '编辑',id: 'edit'},{title: '删除',id: 'del'}],click: function(menudata){if(menudata.id === 'del'){layer.confirm('真的删除行么', function(index){obj.del(); //删除对应行(tr)的DOM结构layer.close(index);//向服务端发送删除指令});} else if(menudata.id === 'edit'){layer.msg('编辑操作,当前行 ID:'+ data.id);}},align: 'right' //右对齐弹出(v2.6.8 新增),style: 'box-shadow: 1px 1px 10px rgb(0 0 0 / 12%);' //设置额外样式})}});//执行一个轮播实例carousel.render({elem: '#test1',width: '100%' //设置容器宽度,height: 200,arrow: 'none' //不显示箭头,anim: 'fade' //切换动画方式});//将日期直接嵌套在指定容器中var dateIns = laydate.render({elem: '#laydateDemo',position: 'static',calendar: true //是否开启公历重要节日,mark: { //标记重要日子'0-10-14': '生日','2020-01-18': '小年','2020-01-24': '除夕','2020-01-25': '春节','2020-02-01': '上班'} ,done: function(value, date, endDate){if(date.year == 2017 && date.month == 11 && date.date == 30){dateIns.hint('一不小心就月底了呢');}},change: function(value, date, endDate){layer.msg(value)}});//分页laypage.render({elem: 'pageDemo' //分页容器的id,count: 1000 //数据总数,limit: 10 //每页显示的数据条数,skin: '#1E9FFF' //自定义选中色值//,layout: ['prev', 'page', 'next', 'count', 'limit', 'refresh', 'skip'] //自定义排版,jump: function(obj, first){if(!first){layer.msg('第'+ obj.curr +'页', {offset: 'b'});}}});//上传upload.render({elem: '#uploadDemo',url: '' //此处配置你自己的上传接口即可,done: function(res){layer.msg('上传成功');layui.$('#uploadDemoView').removeClass('layui-hide').find('img').attr('src', res.files.file);console.log(res)},before: function(){layer.msg('上传中', {icon: 16, time: 0});}});//滑块var sliderInst = slider.render({elem: '#sliderDemo',input: true //输入框});//底部信息var footerTpl = lay('#footer')[0].innerHTML;lay('#footer').html(layui.laytpl(footerTpl).render({})).removeClass('layui-hide');
});
</script>

进行接口测试是否成功添加布局数据:

还是和之前一样,并且通过F12发现还报错了

这个报错原因,意思是没有加载完就使用:解决方法添加window.οnlοad=function(){ }把index页面的script样式给包括住

再次测试:

成功

我们可以把main控制器中index页面不需要的布局删除

<script>window.onload = function () {//加载模块layui.use(function () { //亦可加载特定模块:layui.use(['layer', 'laydate', function(){//得到各种内置组件var layer = layui.layer //弹层, laypage = layui.laypage //分页, laydate = layui.laydate //日期, table = layui.table //表格, carousel = layui.carousel //轮播, upload = layui.upload //上传, element = layui.element //元素操作, slider = layui.slider //滑块, dropdown = layui.dropdown //下拉菜单//向世界问个好layer.msg('Hello World');//监听Tab切换element.on('tab(demo)', function (data) {layer.tips('切换了 ' + data.index + ':' + this.innerHTML, this, {tips: 1});});//执行一个 table 实例table.render({elem: '#demo', height: 420, url: '/demo/table/user/' //数据接口, url: '../demo/table/user/-page=1&limit=20.js' //数据接口, title: '用户表', page: true //开启分页, toolbar: 'default' //开启工具栏,此处显示默认图标,可以自定义模板,详见文档, totalRow: true //开启合计行, cols: [[ //表头{ type: 'checkbox', fixed: 'left' }, { field: 'id', title: 'ID', width: 80, sort: true, fixed: 'left', totalRowText: '合计:' }, { field: 'username', title: '用户名', width: 80 }, { field: 'experience', title: '积分', width: 90, sort: true, totalRow: true }, { field: 'sex', title: '性别', width: 80, sort: true }, { field: 'score', title: '评分', width: 80, sort: true, totalRow: '{{ parseInt(d.TOTAL_NUMS) }} 分' }, { field: 'city', title: '城市', width: 150 }, { field: 'sign', title: '签名', width: 200 }, { field: 'classify', title: '职业', width: 100 }, { field: 'wealth', title: '财富', width: 135, sort: true, totalRow: true }, { fixed: 'right', width: 150, align: 'center', toolbar: '#barDemo' }]]});//监听头工具栏事件table.on('toolbar(test)', function (obj) {var checkStatus = table.checkStatus(obj.config.id), data = checkStatus.data; //获取选中的数据switch (obj.event) {case 'add':layer.msg('添加');break;case 'update':if (data.length === 0) {layer.msg('请选择一行');} else if (data.length > 1) {layer.msg('只能同时编辑一个');} else {layer.alert('编辑 [id]:' + checkStatus.data[0].id);}break;case 'delete':if (data.length === 0) {layer.msg('请选择一行');} else {layer.msg('删除');}break;};});//监听行工具事件table.on('tool(test)', function (obj) { //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值"var data = obj.data //获得当前行数据, layEvent = obj.event; //获得 lay-event 对应的值if (layEvent === 'detail') {layer.msg('查看操作');} else if (layEvent === 'more') {//下拉菜单dropdown.render({elem: this //触发事件的 DOM 对象, show: true //外部事件触发即显示, data: [{title: '编辑', id: 'edit'}, {title: '删除', id: 'del'}], click: function (menudata) {if (menudata.id === 'del') {layer.confirm('真的删除行么', function (index) {obj.del(); //删除对应行(tr)的DOM结构layer.close(index);//向服务端发送删除指令});} else if (menudata.id === 'edit') {layer.msg('编辑操作,当前行 ID:' + data.id);}}, align: 'right' //右对齐弹出(v2.6.8 新增), style: 'box-shadow: 1px 1px 10px rgb(0 0 0 / 12%);' //设置额外样式})}});//分页laypage.render({elem: 'pageDemo' //分页容器的id, count: 1000 //数据总数, limit: 10 //每页显示的数据条数, skin: '#1E9FFF' //自定义选中色值//,layout: ['prev', 'page', 'next', 'count', 'limit', 'refresh', 'skip'] //自定义排版, jump: function (obj, first) {if (!first) {layer.msg('第' + obj.curr + '页', { offset: 'b' });}}});});}
</script>

编写数据接口

大致思路:

1、先在Model层新建类将我们要获取到的数据从DataDepository获取出来

2、Service层编写业务逻辑

3、Controller层编写方法调用Service层,形成接口

4、获取接口,前端样式调用接口

5、在前端接口对需要的数据进行绑定

6、测试页面

我们先获取医生列表的数据,这个类Model层就可以先不用新建类,因为在DataDepository层就有Doctor医生列表的属性字段。

跳到第二步,编写Service层

为了区分前面写的登录写的接口,这里我们要用到的是医生列表数据,所以我们新建一个接口以及对应的实现类(IDoctorServiceDoctorService)

IDoctorService:

DoctorService:

接口编写方法,实现类编写逻辑代码

Controller层调用方法,调用之前先依赖注入刚刚创建的接口IDoctorService和实现类DoctorService

依赖注入:

同时在Controller层创建一个新的控制器医生管理器,这样集中管理医生列表的数据,命名为DoctorController.cs

同时进行属性的调用

调用接口方法IDoctorService,实现接口数据

记得加上jwt验证权限

进行接口数据访问,能够获得到数据,说明已经成功了

返回给前端的样式需要进行完善,统一返回数据格式,显得专业高大上,类似于这种

先在Model层建立一个返回前端样式数据的类HttpResModel.cs,注意,这里的字段不要打错字,不然会造成前端无法接收到数据

        /// <summary>/// 状态码,code==0就是成功,其它可以自定义/// </summary>public int code { get; set; }/// <summary>/// msg提示信息:msg:成功/// </summary>public string msg { get; set; }/// <summary>/// count数据的总条数/// </summary>public int count { get; set; }/// <summary>/// data:具体的数据/// </summary>public T data { get; set; }

效果:

我们立马去DoctorController控制层编写方法看看两者的效果:

紧接着去Main控制层下的index页面调用我们生成的数据接口,将数据渲染到layui样式布局里面

接着通过接口的数据渲染到页面上去

实现数据渲染效果:

最后更改管理系统的英文字符,_Layout2.cshtml类中修改

链接多表渲染数据

大致思路梳理:在Model层先建一个类去存放我们有关医生的信息属性,一样的数据是从DataDepository中获取,属性字段要一样-->Service层,接口编写新的方法,实现类编写逻辑代码-->Controller层测试接口是否获取到我们需要的数据-->前端样式调用接口,最后将数据渲染到页面

Join和Linq两种方式进行连接

像我们前面的数据渲染是医生类里面就有的属性,我们可以跳过Mocel层这个步骤,可是我们的数据库往往会存在主键,多个表之间都会存在联系,为了获取到其他表的数据,需要多一步Model层进行数据封装

Join连接

1、Model层创建类DoctorViewModel.cs

2、 Service层,接口(IDoctorService)和实现类(DoctorService)

IDoctorService:

DoctorService:

//连接两张表数据-->Join(内连接)方法public List<DoctorViewModel> GetViewModel(){return _hospitalContext.Doctors.Join( _hospitalContext.Departments,  //要关联的表名doct => doct.DeptId,        //指定用第一张表(Doctor表)的哪个字段去关联dept => dept.DeptId,        //指定用第二张表(Department表)的哪个字段去关联(t1, t2) => new DoctorViewModel //关联之后要返回两张表的哪些字段值{DId = t1.DId,   DeptId = t1.DeptId,Password = t1.Password,PhoneNum = t1.PhoneNum,RealName = t1.RealName,UserName = t1.UserName,RId = t1.RId,Sex = t1.Sex,DName = t2.DName,DDesc = t2.DDesc}).ToList();}

3、Controller层测试

4、前端样式调用接口,渲染数据

在Main控制层的index页面进行需改

5、效果展示

Join链接三张表

但是需要注意数据表中的所关联的主键和复键,有些表需要先连接才能根据所连接上的表中的主键才能去连接其他的数据表,在编写逻辑代码的时候也要有顺序

1、修改Model层DoctorViewModel.cs

2、 修改Service层,接口(IDoctorService)和实现类(DoctorService)

IDoctorService:

DoctorService:

代码:

public List<DoctorViewModel> GetViewModel2(){//Join(内连接)return _hospitalContext.Doctors.Join(_hospitalContext.Departments, //要关联的表名doct => doct.DeptId,  //指定用第一张表(Doctor表)的哪个字段去关联dept => dept.DeptId,  //指定用第二张表(Department表)的哪个字段去关联(t1, t2) => new DoctorViewModel //关联之后要返回两张表的哪些字段值{DId = t1.DId,DeptId = t1.DeptId,Password = t1.Password,PhoneNum = t1.PhoneNum,RealName = t1.RealName,UserName = t1.UserName,RId = t1.RId,Sex = t1.Sex,DName = t2.DName,DDesc= t2.DDesc}).Join(_hospitalContext.DoctorProfessionals,doctView => doctView.DId,dProf => dProf.DId, (t1, t2) => new DoctorViewModel{DId = t1.DId,DeptId = t1.DeptId,Password = t1.Password,PhoneNum = t1.PhoneNum,RealName = t1.RealName,UserName = t1.UserName,RId = t1.RId,Sex = t1.Sex,DName = t1.DName,DDesc=t1.DDesc,PId = t2.PId.Value}).Join(_hospitalContext.ProfessionalTitles, doctView2 => doctView2.PId, pTitle => pTitle.PId,(t1, t2) => new DoctorViewModel{DId = t1.DId,DeptId = t1.DeptId,Password = t1.Password,PhoneNum = t1.PhoneNum,RealName = t1.RealName,UserName = t1.UserName,RId = t1.RId,Sex = t1.Sex,DName = t1.DName,DDesc = t1.DDesc,PId = t1.PId,pName = t2.PName}).ToList();

3、Controller层测试

测试接口数据:

4、前端样式调用接口,渲染数据

5、效果展示

Linq连接

我们上面使用Join连接表的时候发现,当连接多个表的数据的时候重复的步骤很多,比较冗杂。使用Linq连接就能解决这个问题

1、Model层用以及编辑好的DoctorViewModel.cs.cs

2、修改Service层,接口(IDoctorService)和实现类(DoctorService)

IDoctorService:(接口)

DoctorService:(实现类操作)

代码:

 //连接多表数据-->Linq(查询)方法public List<DoctorViewModel> GetViewModel3(){//foreach(LINQ查询),写法更像数据库连接操作var doctQuery = from doct in _hospitalContext.Doctorsjoin dept in _hospitalContext.Departmentson doct.DeptId equals dept.DeptIdjoin dProf in _hospitalContext.DoctorProfessionalson doct.DId equals dProf.DIdjoin pTitle in _hospitalContext.ProfessionalTitleson dProf.PId equals pTitle.PIdselect new DoctorViewModel{DId = doct.DId,DeptId = doct.DeptId,Password = doct.Password,PhoneNum = doct.PhoneNum,RealName = doct.RealName,UserName = doct.UserName,RId = doct.RId,Sex = doct.Sex,DName = dept.DName,DDesc= dept.DDesc,PId = dProf.PId.Value,pName = pTitle.PName};return doctQuery.ToList();}

3、Controller层测试

测试接口:

访问数据一样,但是接口改变了

4、前端样式调用接口,渲染数据

5、效果展示

Join连接实现的效果一样

实现分页

实现分页要在连接多表的基础上实现布局

1、Model层用以及编辑好的DoctorViewModel.cs.cs

2、修改Service层,接口(IDoctorService)和实现类(DoctorService)

IDoctorService:(接口)

DoctorService:(实现类操作)

 JWT验证千万不要忘记了

代码:

//实现分页/// <summary>/// page页码,1表示第一页,2:表示第二页/// </summary>/// <param name="page"></param>/// <param name="limit">每页的条数</param>/// //out:把值返出去给别人用/// <returns></returns>public List<DoctorViewModel> GetListPage(int page, int limit, out int totalCount){//foreach(LINQ查询),写法更像数据库连接操作var doctQuery = from doct in _hospitalContext.Doctorsjoin dept in _hospitalContext.Departmentson doct.DeptId equals dept.DeptIdjoin dProf in _hospitalContext.DoctorProfessionalson doct.DId equals dProf.DIdjoin pTitle in _hospitalContext.ProfessionalTitleson dProf.PId equals pTitle.PIdselect new DoctorViewModel{DId = doct.DId,DeptId = doct.DeptId,Password = doct.Password,PhoneNum = doct.PhoneNum,RealName = doct.RealName,UserName = doct.UserName,RId = doct.RId,Sex = doct.Sex,DName = dept.DName,DDesc = dept.DDesc,PId = dProf.PId.Value,pName = pTitle.PName};//OrderBy:排序//OrderBy:升序(1,2,3,4...),OrderByDescending:降序,(5,4,3,2,1)//Skip:跳过,page=1:0;page=2:5//Take:要取多少条数据totalCount = doctQuery.Count();//分页之前,表里面的总条数return doctQuery.OrderByDescending(m => m.DId).Skip((page - 1) * limit).Take(limit).ToList();}

3、Controller层测试

测试分页接口,但是分页接口属于有参方法,我们直接访问该接口无法进行传参,不能像之前一样直接访问该接口,但是直接跳到第四步进行检验测试

4、前端样式调用分页接口

因为我们的分页设置是10条数据进行分页,我们的数据库数据没有这么多,需要添加多几条数据上去来达到分页效果

因为主键复键关系,我们添加数据的时候有关联的表都要添加上数据,不然只添加一个表会造成访问的时候没有该数据

 

完成分页效果

增删改查

查询

思路:设计前端界面按钮-->进行Service层逻辑编写-->Controller层编写接口-->前端调用进行参数获取

1、添加界面按钮-->main控制器的index页面下操作

<form class="layui-form" action=""><div class="layui-form-item"><div class="layui-inline"><label class="layui-form-label">关键字</label><div class="layui-input-inline"><input type="text" name="keyword" id="keyword" placeholder="请输入姓名/部门名称/手机号"autocomplete="off" class="layui-input"></div></div><div class="layui-inline"><label class="layui-form-label">验证邮箱</label><div class="layui-input-inline"><input type="text" name="email" autocomplete="off" class="layui-input"></div></div><div class="layui-inline"><div class="layui-input-inline"><button class="layui-btn" lay-submit="" lay-filter="demo1">搜索</button></div></div></div>
</form>

2、Service层逻辑编写

在分页的基础上实现查询功能

IDoctorService:(接口)

DoctorService:(实现类操作)

代码:

//查询功能public List<DoctorViewModel> Inquire(int page, int limit, string keyword, out int totalCount){//foreach(LINQ查询),写法更像数据库连接操作var doctQuery = from doct in _hospitalContext.Doctorsjoin dept in _hospitalContext.Departmentson doct.DeptId equals dept.DeptIdjoin dProf in _hospitalContext.DoctorProfessionalson doct.DId equals dProf.DIdjoin pTitle in _hospitalContext.ProfessionalTitleson dProf.PId equals pTitle.PIdselect new DoctorViewModel{DId = doct.DId,DeptId = doct.DeptId,Password = doct.Password,PhoneNum = doct.PhoneNum,RealName = doct.RealName,UserName = doct.UserName,RId = doct.RId,Sex = doct.Sex,DName = dept.DName,DDesc = dept.DDesc,PId = dProf.PId.Value,pName = pTitle.PName};// 搜索if (!string.IsNullOrEmpty(keyword)){//Contains(包含)类似indexOf//"赵三丰".contains("三"):模糊搜索,like//var str = "hello";//str=str + "world";//hello worlddoctQuery = doctQuery.Where(doctView => doctView.RealName.Contains(keyword) ||doctView.DName.Contains(keyword) || doctView.PhoneNum == keyword);}//OrderBy:排序//OrderBy:升序(1,2,3,4...),OrderByDescending:降序,(5,4,3,2,1)//Skip:跳过,page=1:0;page=2:5//Take:要取多少条数据totalCount = doctQuery.Count();//分页之前,表里面的总条数return doctQuery.OrderByDescending(m => m.DId).Skip((page - 1) * limit).Take(limit).ToList();}

3、Controller层编写接口

4、前端调用进行参数获取

进行测试:

当我们查询名字的时候报错,提示我们需要引入JQ

引入JQ,在_Layout2.cshtml上操作

再次测试:

姓名模糊查询:

部门模糊查询:

联系方式查询:

为空显示全部数据:

删除

删除分为单条删除和批量删除

实现删除思路:设进行Service层逻辑编写-->Controller层编写接口-->前端调用接口进行删除判断

1、Service层

IDoctorService:(接口)

DoctorService:(实现类操作)

代码:

//实现删除public int Delete(int id){//var doctor = _hospitalContext.Doctors.Where(doct => doct.DId == id).FirstOrDefault();//如果是通过主键ID删除的话,那么可以直接使用find方法var doctor = _hospitalContext.Doctors.Find(id);if (doctor != null){var doctProf = _hospitalContext.DoctorProfessionals.Where(dProf => dProf.DId == id).FirstOrDefault();//因为外键的原因,所以要删除doctor表的数据,必须先删除DoctorProfessional表的数据_hospitalContext.DoctorProfessionals.Remove(doctProf);//Remove:删除,在内存中删除_hospitalContext.Doctors.Remove(doctor);//SaveChanges:保存更改,只有调用了这个方法才会真正地去数据库里面删除//SaveChanges:会返回受影响的行数return _hospitalContext.SaveChanges();}return 0;}

2、Controller层

代码:

//实现删除[AllowAnonymous]public IActionResult Delete(int id){var httpResModel = new Hospital.Model.HttpResModel<int>();httpResModel.code = 0;httpResModel.msg = "删除成功";var ret = _doctorService.Delete(id);if (ret == 0){httpResModel.code = -1;httpResModel.msg = "删除失败";}httpResModel.count = 0;httpResModel.data = ret;return Json(httpResModel);}

3、前端调用接口

4、选中id进行删除

5、前往数据库,查看是否还有该数据,验证是否真正删除

实现批量删除

大致思路和删除是一样

1、Service层

IDoctorService:(接口)

DoctorService:(实现类操作)

注意:如果逻辑代码实现的时候返回的数据是字符串的话,后台实现的数据库方法是模糊查询,然后有些数据因为关联会出现问题

代码:

//实现批量删除public int DelAll(string ids){if (string.IsNullOrEmpty(ids)){return 0; //删除失败}//StringSplitOptions.RemoveEmptyEntries去掉空白项//string[]var idArr = ids.Split(",", StringSplitOptions.RemoveEmptyEntries);//string//var idArr = ids;//id in(1,33,22)var doctors = _hospitalContext.Doctors.Where(doct => idArr.Contains(doct.DId.ToString())).ToList();if (doctors != null && doctors.Count > 0){var doctProfs = _hospitalContext.DoctorProfessionals.Where(doctProf => idArr.Contains(doctProf.DId.ToString())).ToList();//RemoveRange同时删除多条数据_hospitalContext.DoctorProfessionals.RemoveRange(doctProfs);_hospitalContext.Doctors.RemoveRange(doctors);return _hospitalContext.SaveChanges();}return 0;}

2、Controller层

代码:

//实现批量删除[AllowAnonymous]public IActionResult DelAll(string ids){var httpResModel = new HttpResModel<int>();httpResModel.code = 0;httpResModel.msg = "删除成功";var ret = _doctorService.DelAll(ids);if (ret == 0){httpResModel.code = -1;//删除失败httpResModel.msg = "删除失败";}httpResModel.count = 0;httpResModel.data = ret;return Json(httpResModel);}

3、前端调用接口并编写删除判断逻辑

4、选中多个id进行删除

5、前往数据库,查看是否还有该数据,验证是否真正删除

增加数据

大致思路分析:添加数据首先要有一个表格填写想要增加的数据,所以需要新建一个添加的页面-->Service层改动--Controller层编写接口-->前端样式调用接口-->数据库查看新增数据

1、进行添加页面样式布局,新增页面视图为add

进行编辑布局:

代码:

@{ViewData["Title"] = "Add";Layout = "~/Views/Shared/_Layout2.cshtml";
}
@*学生练习页面*@
<form class="layui-form" action="" lay-filter="addform"><div class="layui-form-item"><label class="layui-form-label">用户名</label><div class="layui-input-block"><input type="text" name="username" lay-verify="required" lay-reqtext="用户名是必填项,岂能为空?" placeholder="请输入用户名" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item"><label class="layui-form-label">密码</label><div class="layui-input-block"><input type="password" name="password" lay-verify="required" lay-reqtext="密码是必填项,岂能为空?" autocomplete="off" placeholder="请输入密码" class="layui-input"></div></div><div class="layui-form-item"><label class="layui-form-label">真实姓名</label><div class="layui-input-block"><input type="text" name="realname" lay-verify="required" lay-reqtext="真实姓名是必填项,岂能为空?" placeholder="请输入真实姓名" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item"><label class="layui-form-label">手机号</label><div class="layui-input-block"><input type="text" name="phonenum" lay-verify="required|phone" lay-reqtext="手机号是必填项,岂能为空?" placeholder="请输入手机号" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item"><label class="layui-form-label">性别</label><div class="layui-input-block"><input type="radio" name="sex" value="男" title="男" checked=""><input type="radio" name="sex" value="女" title="女"></div></div><div class="layui-form-item"><label class="layui-form-label">所属部门</label><div class="layui-input-block"><select name="deptID" id="deptID" lay-filter="department"><option value=""></option>@* <option value="0">写作</option><option value="1">阅读</option><option value="2">游戏</option><option value="3">音乐</option><option value="4">旅行</option>*@</select></div></div><div class="layui-form-item"><label class="layui-form-label">职称</label><div class="layui-input-block"><select name="pid" id="pfession"><option value=""></option>@* <option value="0">写作</option><option value="1">阅读</option><option value="2">游戏</option><option value="3">音乐</option><option value="4">旅行</option>*@</select></div></div><div class="layui-form-item"><label class="layui-form-label">角色</label><div class="layui-input-block"><select name="RId" id="role" lay-filter="role"><option value=""></option>@* <option value="0">写作</option><option value="1">阅读</option><option value="2">游戏</option><option value="3">音乐</option><option value="4">旅行</option>*@</select></div></div><div class="layui-form-item"><div class="layui-input-block"><button type="submit" class="layui-btn" lay-submit="" lay-filter="btnsubmit">立即提交</button></div></div>
</form>
<div style="height:200px;"></div>
<script>window.onload = function () {layui.use(function () {var form = layui.form;form.on('submit(btnsubmit)', function (data) {//console.log(data.elem) //被执行事件的元素DOM对象,一般为button对象//console.log(data.form) //被执行提交的form对象,一般在存在form标签时才会返回//console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value}var data1 = data.field;return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。});});}
</script>

效果:

所属部门这几个不应该是我们自己填写,而是供我们选择的一个下拉框,所以需要对这几个进行一个数据绑定,实现下拉渲染

这三个下拉选项对应着不同的数据表,所以需要我们新建接口获取对应下拉数据

2、Service层处理业务逻辑

进行下拉渲染接口编写:

所属部门:

IDeptService:(实现类操作)

DeptService:(实现类操作)

Controller层:

依赖注入:

创建DeptController控制器并实现接口:

职称:

角色:

添加页面进行下拉绑定:记得更换自己的接口名称

代码:

//下拉框绑定部门名称$.get("/dept/getdeptlist", function (data) {if (data != null && data.length > 0) {var strOptionHtml = "";for (var i = 0; i < data.length; i++) {strOptionHtml += '<option value="' + data[i].deptId + '">' + data[i].dName + '</option>';}$("#deptID").append(strOptionHtml);form.render("select");}});

下拉渲染效果:

剩下的职称和角色步骤一样,就不过多复述

实现添加功能

1、Service层编写:

IDoctorService:(接口)

DoctorService:(实现类操作)

2、Controller层:

形成接口

3、前端样式调用接口

4、效果测试

数据库检查数据

更改数据

大致思路和增加数据一样就不过多复述

更改数据和增加一样都要先有一个表去进行更改,但是我们根据id选中数据进行更改的时候,还要将该数据的信息显示出来

1、增加一个修改的页面

直接复制前面我们的添加页面就好了,然后Controller层添加接口用来访问该页面

新建接口访问页面

2、Service层

因为修改数据是根据id来选中该数据,需要获取到单条数据

IDoctorService:

DoctorService:

代码:

//获取单条数据public DoctorViewModel Get(int id){var doctQuery = from doct in _hospitalContext.Doctorsjoin dProf in _hospitalContext.DoctorProfessionalson doct.DId equals dProf.DIdwhere doct.DId == idselect new DoctorViewModel{DId = doct.DId,DeptId = doct.DeptId,Password = doct.Password,PhoneNum = doct.PhoneNum,RealName = doct.RealName,UserName = doct.UserName,RId = doct.RId,Sex = doct.Sex,PId = dProf.PId.Value,//职称id};return doctQuery.FirstOrDefault();}

修改控制层:

 //新增添加数据视图[AllowAnonymous]/// <summary>/// 编辑/// </summary>/// <returns></returns>public IActionResult Edit(int id){//为了不报空引用异常//?和??的区别?//??代表的是判断左边的值是不是等于null,如果等于null那么返回右侧的值,//否则就返回左边的值//a==b?a:b//var doct1 =_doctorService?.Get(id);//null.Get()var doct = _doctorService.Get(id) ?? new DoctorViewModel();return View(doct);}

将修改数据的接口放到前端样式布局里面

测试:

接着根据id跳转修改属性id的时候,进行跳转之后的数据渲染

但是性别的数据绑定需要进行一些逻辑判断

下拉框的绑定需要设置选中操作

再次测试:

此时数据渲染成功

进行修改逻辑编写:

IDoctorService:

DoctorService:

代码:

//修改数据public int Update(Doctor doctor, int pid){_hospitalContext.Doctors.Update(doctor);//获取到数据var doctProf = _hospitalContext.DoctorProfessionals.Where(doctProf => doctProf.DId == doctor.DId).FirstOrDefault();//对返回值进行判断if (doctProf != null){_hospitalContext.DoctorProfessionals.Update(doctProf);}return _hospitalContext.SaveChanges();}

再次进行Controller层操作:

更给前端样式接口:

还记得我们的接口吗?

有关int参数,就是用来获取我们要更改的id的值,是我们必须要进行传入的值

传入方式:

5、最后效果

结尾

ASP.netCore 笔记整理(自用)相关推荐

  1. ASP 学习笔记整理

    在看高手写的asp代码中看到asp代码用with来表示对象,其asp结构形式 with -End with. 代码如下: <% sql = "select * from table&q ...

  2. ASP.NET Core分布式项目实战(集成ASP.NETCore Identity)--学习笔记

    任务24:集成ASP.NETCore Identity 之前在 Index 页面写了一个 strong 标签,需要加个判断再显示,不然为空没有错误的时候也会显示 @if (!ViewContext.M ...

  3. 笔记整理 asp + vbscript篇

    一.前言 想要找一个知识点,居然找不到,有点郁闷,故而把以前写的笔记整理分类.败笔在于没有任何条理,标题取的也不是很恰当,不能使我看到标题,就知道这份笔记的主要内容是什么.故而简述分类 二.整理 1. ...

  4. 【笔记】设计模式 | 5种设计模式笔记整理

    跟着b站的设计模式教程学的,以下是目前学习了的5种设计模式的笔记整理 设计模式简介 软件设计的现状:由于客户需求等原因需要频繁的变更软件内部的代码.所以能否设计出复用性尽可能高的程序以解决软件设计的复 ...

  5. Linux学习笔记(自用)

    Linux学习笔记(自用) 该笔记由尚硅谷的"3天上手LInux"视频整理而成,若有侵权,请联系作者删除 文章目录 Linux学习笔记(自用) 1. 概述 2. 下载 3.文件与目 ...

  6. JVM学习笔记(自用)

    JVM学习笔记(自用) 文章目录 JVM学习笔记(自用) 1.简介 2.程序计数器 3. 虚拟机栈 4. 方法区 5. 直接内存 6. 垃圾回收 Young Collection Young Coll ...

  7. dw 快速html注释,笔记整理1-HTML基础知识与DW简单使用-工具-站长头条

    笔记整理1 -- HTML基础知识与DW简单使用 笔记整理1 -- HTML基础知识与DW简单使用 概念 客户端和服务器端 文件名.基本名.扩展名 资源文件和站点 什么是HTML 关于W3C W3C的 ...

  8. html语言需要dw吗,HTML笔记整理1 -- HTML基础知识与DW简单使用

    HTML笔记整理1 -- HTML基础知识与DW简单使用概念客户端和服务器端文件名.基本名.扩展名资源文件和站点什么是HTML关于W3CW3C的规范网站与网页基本概念网页的制作网页的基本框架通过记事本 ...

  9. dw边框弧度设置_笔记整理1 -- HTML基础知识与DW简单使用

    笔记整理1 -- HTML基础知识与DW简单使用 笔记整理1 -- HTML基础知识与DW简单使用 概念 客户端和服务器端 文件名.基本名.扩展名 资源文件和站点 什么是HTML 关于W3C W3C的 ...

最新文章

  1. 自动驾驶又陷“派系”之争:该约束行人还是让车更完美
  2. DOM操作之CRUD操作
  3. Vue 安装 less
  4. 分布式架构的水平和垂直扩容
  5. 为什么python除法结果会有小数点0_关于python:为什么整数除法会在许多脚本语言中向下取整?...
  6. netdev_priv() 函数
  7. 继承、关联、聚合、组合的代码表示
  8. swot分析法案例_型男收割机之SWOT分析法——大龄剩女脱单攻略
  9. python鸡兔同笼问题
  10. 【听课笔记】复旦大学遗传学_06基因组
  11. python分组统计excel数据_python中excel数据分组处理
  12. 【快应用】十大手机厂商共推快应用标准
  13. 评估并改善模型的预测性能
  14. STM32的RS485通信
  15. 【奈茶君】STM32F407驱动WS2812
  16. dom4j的一些总结
  17. Linux中使用gzip来压缩/解压 *.gz文件
  18. java中pdf写成base64文件流,Java操作pdf文件与Base64编码相互转换与文件流操作
  19. 游梁式抽油机设计【课程设计(论文)+CAD总装图】
  20. TensorFlow 机器学习秘籍第二版:6~8

热门文章

  1. 敬业!华为23级大佬消耗巨资整理出2000页网络协议最全笔记
  2. P3950 部落冲突
  3. 结合盒子模型,优化明信片
  4. vue H5页面实现海报功能demo
  5. C语言程序设计计算机二级
  6. UI测试用例设计,场景测试法
  7. 计算机未来职业规划400字作文,未来生涯的规划作文
  8. 力扣每日一题——三角形的最大周长
  9. 由一道CTF对10种反调试的探究
  10. 详解k-means++