今天要增加一个通过EF访问数据库的功能,同时写一个增加新用户的接口,
接口访问地址:api/User/AddUser
接口入参:{ "phone":"13200000000", "password":"123456", "nickName":"小赵先生", "state":1 }
接口返回值:{ "code": 1, "message": "数据插入成功" }
开发环境
Visual Studio 2019
.net core 3.0
Sqlserver 2008数据库
Postman
第一步创建类库
在教程一的基础上首先新增3个.NET Core类库----Models
、Bo
、Common
,
Models
:存放EF的一些实体类,EF的DBContent和接口传参Model以及接口返回值Model等一切和对象有关的统统放这里。
Bo
:这里主要处理业务层面的事情,比如将用户信息存放到数据库。
Common
:主要是一些公共类,比如图片上传、Md5签名、DES加密解密等。
创建类库具体步骤如下图:
创建好类库以后可以把里面的
Class1.cs
直接删除添加完类库以后进行类库的关联,
AP
I引用Models
+Bo
+Common
,Bo
引用Models
+Common
3个类库创建完毕以后整个工程目录如下:
然后给每个项目添加EF相关的Nuget包,每个类库要添加的包如下:
这个项目有点.Net三层架构的意思,没有用工场模式,解耦方面也没有特别的考虑,优点就是简单、清晰、一目了然,可以满足小型和中型项目,做个后台管理系统接口或者手机APP接口完全没有问题。
第二步创建一个数据库
一个EF项目的开始总会有人在思考到底DBFirs还是CodeFirst,个人还是比较喜欢DBFirst,数据库设计好了,剩下的项目代码其实90%以上就是数据库的增删改查操作了,所以这个教程也是采用的DBFirst模式。
数据库怎么创建就不写教程了,直接给代码:
数据库名称:xxx
表名称:User
表创建代码如下:
CREATE TABLE [dbo].[User](
[id] [int] IDENTITY(1,1) NOT NULL,--一个自动增长的主键
[phone] [varchar](20) NULL,--用户手机号
[password] [nvarchar](50) NULL,--用户密码
[msgCode] [varchar](10) NULL,--用户最新一次获取的短信验证码
[regTime] [datetime] NULL,--用户注册时间
[nickName] [nvarchar](50) NULL,--用户昵称
[state] [int] NULL,--用户状态
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
注:此处应该说一句,不推荐给表起名User,User在sqlserver中属于关键词,所以在写sql语句的时候要把User表名括起来,比如:select * from [User]
第三步EF相关代码
在Models中XXXEntities中新建2个类,一个表User实体类User.cs
和DbContext类xxxContext.cs
User.cs
代码如下:
using System;
namespace XXX.Models.XXXEntities
{
public partial class User
{
public int Id { get; set; }
public string Phone { get; set; }
public string Password { get; set; }
public string MsgCode { get; set; }
public DateTime? RegTime { get; set; } //此处的问号表示RegTime允许为空
public string NickName { get; set; }
public int? State { get; set; }
}
}
xxxContext.cs
代码如下:
using Microsoft.EntityFrameworkCore;
namespace XXX.Models.XXXEntities
{
public partial class xxxContext : DbContext
{
public xxxContext()
{
}
public xxxContext(DbContextOptions<xxxContext> options)
: base(options)
{
}
public virtual DbSet<User> User { get; set; }
public static string ConStr { get; set; }//用于接收数据库连接字符串
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(ConStr);//设置数据库连接字符串
}
}
}
}
注:如果数据库表非常多,手写数据库表实体类是一件非常烦躁且容易出错的事情,所以可以使用命令自动生成。
1.打开程序包管理器控制台
控制台界面如下:
2.在控制台输入命令代码,默认项目要选择
xxx.Models
这样才能把代码生成到Models
里面Scaffold-DbContext "Server=服务器地址;User Id=用户名;Password=密码;Database=数据库名称;" Microsoft.EntityFrameworkCore.SqlServer -o XXXEntities -f -t StateMgr
注释:
-o 后面指定文件夹,
-f 表示是否覆盖原文件
-t 后面跟表名
默认生成的xxxContext.cs
自动把数据库连接字符串写在项目中了,这样不便于后期维护,推荐写在配置文件中。
第四步配置数据库连接字符串
- 在XXX.api项目中找到
appsettings.json
文件增加数据库连接字符串
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"xxxDB": "Server=服务器地址;User Id=数据库登录名;Password=密码;Database=数据库名称;"
}
}
- 在XXX.api项目中找到
Startup.cs
文件获取数据库连接字符串
也可以通过services.AddDbContext<Models.XXXEntities.xxxContext>(options => { options.UseSqlServer(conn); });
注册数据库连接字符串,但是EF的实体类放在了Models中不知道为什么这样写总提示没有配置数据库,于是改成了通过一个全局变量来设置数据库连接字符串的方式。
关于EF相关的写完了,下面开始写一个接口。
第五步定义接口
- 在XXX.Bo中新建一个
UserBo.cs
类
using System.Linq;
namespace XXX.Bo
{
public class UserBo
{
public static Models.XXXEntities.xxxContext db = new Models.XXXEntities.xxxContext();
/// <summary>
/// 增加一个用户数据
/// </summary>
/// <param name="model"></param>
public static Models.User.AddUserR AddUser(Models.User.AddUserP model)
{
var r = new Models.User.AddUserR();
Models.XXXEntities.User userSearch = (from u in db.User where u.Phone == model.phone select u).FirstOrDefault();
if (userSearch==null)
{
Models.XXXEntities.User user = new Models.XXXEntities.User();
user.Phone = model.phone;
user.Password = model.password;
user.NickName = model.nickName;
user.State = model.state;
db.User.Add(user);
int i =db.SaveChanges();
if (i>0)
{
r.code = 1;
r.message = "数据插入成功";
}
else
{
r.code = 0;
r.message = "数据插入成功";
}
}
else
{
r.code = 0;
r.message = "手机号已经存在";
}
return r;
}
}
}
//EF我是用Linq的方式写的,所以using只引用了System.Ling
- 在XXX.api中
UserController.cs
增加一个接口
/// <summary>
/// 增加一个用户
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
public IActionResult AddUser([FromBody]Models.User.AddUserP model)
{
var r = Bo.UserBo.AddUser(model);
return Ok(r);
}
第六步测试
接口写好了,程序员要自己测试下代码,这是一个非常好的习惯,要从写第一行代码开始就要养成,我们测试下
打开postman输入测试数据和接口地址,红框里是需要注意的内容
我们打个断点查看下webapi接收到的数据
第一次提交返回结果
第二次提交返回结果
通过这2个教程基本上就掌握如何用NetCore写一个webapi了,不过接口写好了是不是该提供一份棒棒的接口文档呢?答案必须是YES,下一个教程将带你去给接口生成一个棒棒的接口文档。
补充
Models类库
注:P结尾的model表示参数实体对象,R结尾的model表示返回结果实体对象
AddUserP.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace XXX.Models.User
{
public class AddUserP
{
public string phone { get; set; }
public string password { get; set; }
public string nickName { get; set; }
public int state { get; set; }
public string sign { get; set; }
}
}
AddUserR.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace XXX.Models.User
{
public class AddUserR
{
public int code { get; set; }
public string message { get; set; }
}
}