IDE: vs2019
Core 版本:.NET Core3.1
# 调整启动方式
在进行开发 webapi 项目时,我们为了方便监听程序日志,我们可以选择一控制台方式启动。
# 配置启动主页
在 launchSetting.json
里我们对启动项进行详细设置。
"WebCore": { | |
"commandName": "Project", | |
"launchBrowser": true, | |
"launchUrl": "index.html", // 启动时的 Url | |
"environmentVariables": { | |
"ASPNETCORE_ENVIRONMENT": "Development" | |
}, | |
"applicationUrl": "http://localhost:5000" | |
} |
# 启用静态资源
在项目根目录创建一个名为 wwwroot
的文件夹用于存放静态资源。
在 Startup.cs
中, public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
方法中添加:
app.UseStaticFiles(); |
# 启用跨域
在 ConfigureServices
设置跨域
// 跨域 | |
services.AddCors( | |
m => m.AddPolicy(Any, a => a.SetIsOriginAllowed(_ => true). | |
AllowAnyMethod(). | |
AllowAnyHeader(). | |
AllowCredentials())); |
在 Configure
设置启用跨域
app.UseCors(Any); |
在 Controller 中启动跨域
[EnableCors("Any")] |
# 启用 Session 和 Cookie
# 基础配置
在 ConfigureServices
中
// 启用 Session | |
services.AddSession(options => | |
{ | |
options.Cookie.Name = ".WebCore.Session"; | |
options.IdleTimeout = System.TimeSpan.FromSeconds(120);// 设置 session 的过期时间 | |
options.Cookie.HttpOnly = true;// 设置在浏览器不能通过 js 获得该 cookie 的值 | |
}); |
在 Configure
中
app.UseSession();//UseSession 配置在 UseMvc 之前 |
# Session 帮助类
using Microsoft.AspNetCore.Http; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace WebCore.Tool | |
{ | |
/// <summary> | |
/// Session 帮助类 | |
/// </summary> | |
public class SessionHelper | |
{ | |
private IHttpContextAccessor _accessor; | |
private ISession _session; | |
private IRequestCookieCollection _requestCookie; | |
private IResponseCookies _responseCookie; | |
public SessionHelper(HttpContext context) | |
{ | |
_session = context.Session; | |
_requestCookie = context.Request.Cookies; | |
_responseCookie = context.Response.Cookies; | |
} | |
/// <summary> | |
/// 设置 session 值 | |
/// </summary> | |
/// <param name="session"></param> | |
/// <param name="key"> 键 & lt;/param> | |
/// <param name="value"> 值 & lt;/param> | |
public void SetSession(string key, string value) | |
{ | |
var bytes = System.Text.Encoding.UTF8.GetBytes(value); | |
_session.Set(key, bytes); | |
} | |
/// <summary> | |
/// 获取 Session 值 | |
/// </summary> | |
/// <param name="key"></param> | |
/// <returns></returns> | |
public string GetSession(string key) | |
{ | |
byte[] bytes; | |
_session.TryGetValue(key, out bytes); | |
if (bytes == null) | |
{ | |
return ""; | |
} | |
var value = System.Text.Encoding.UTF8.GetString(bytes); | |
if (string.IsNullOrEmpty(value)) | |
{ | |
value = string.Empty; | |
} | |
return value; | |
} | |
} | |
} |
❤️ 要使用 Session 和 Cookie,可以使用 IHttpContextAccessor
来设置。
// 存储 Cookie | |
accessor.HttpContext.Response.Cookies.Append("userId", res2.Id.ToString()); | |
// 取得 Cookie | |
var userId = string.Empty; | |
accessor.HttpContext.Request.Cookies.TryGetValue("userId", out userId); |
# 依赖注入
在 startup.cs
中 ConfigureServices.cs
的方法中注入:
// 使用泛型注入一类对象 | |
services.AddTransient<WebCore.Services.OrderService>(); |
在需要使用的地方的构造函数中注入:
private readonly OrderService orderService; | |
public OrderController(OrderService order) | |
{ | |
this.orderService = order; | |
} |
# EF 连接数据库
# 连接 Mysql
▶️首先需要安装对应的依赖,包括:
😃记得和 netcore 的版本号对应,此文 netcore 版本号为 3.1
- EntityFrameworkCore 3.1.8
- EntityFrameworkCore.Tools 3.0.1
- Pomelo.EntityFrameworkCore.MySql 3.2.0
# 配置 Mysql 连接字符串
"ConnectionStrings": { | |
"MysqlConnection": "Data Source=localhost;Database=coreDb;User ID=root;Password=;pooling=true;port=3306;sslmode=none;CharSet=utf8;" | |
}, |
# 注册连接
// 连接数据库 | |
var connection = Configuration.GetConnectionString("MysqlConnection"); | |
services.AddDbContext<CoreDbContext>(t => t.UseMySql(connection)); |
# EF 连接类
在 EF 中我们需要创建一个数据库上下文对象的类,这个类需要继承自 DbContext
。
using Microsoft.EntityFrameworkCore; | |
namespace WebCore.Models | |
{ | |
/// <summary> | |
/// 核心数据库上下文对象 | |
/// </summary> | |
public class CoreDbContext : DbContext | |
{ | |
public DbSet<User> Users { get; set; } | |
public DbSet<Flower> Flowers { get; set; } | |
public DbSet<Order> Orders { get; set; } | |
public DbSet<Cart> Carts { get; set; } | |
public DbSet<Address> Addresses { get; set; } | |
public DbSet<LeaveWord> LeaveWords { get; set; } | |
public DbSet<FlowerOrder> FlowerOrders { get; set; } | |
public DbSet<FlowerPicture> FlowerPictures { get; set; } | |
public CoreDbContext(DbContextOptions<CoreDbContext> options) : base(options) | |
{ | |
} | |
protected override void OnModelCreating(ModelBuilder modelBuilder) | |
{ | |
base.OnModelCreating(modelBuilder); | |
} | |
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) | |
{ | |
base.OnConfiguring(optionsBuilder); | |
} | |
} | |
} |
# EF 迁移指令
☑️我们可以使用一下指令来操作 EF 迁移。
每次使用 EF 迁移后都会生成一个迁移类,并在数据库中存储迁移的相关信息,可以很方便的使用数据回滚。
指令 | 作用 |
---|---|
Add-Migration xxx | 添加一次迁移 迁移名称为 xxx |
Update-Database | 将当前迁移更新于数据库 |
# 搭建 Model
▶️ 我们可以构建一个基础实体类方便管理共有属性。
namespace WebCore.Models | |
{ | |
public class BaseEntity | |
{ | |
[Key] | |
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] | |
public int Id { get; set; } | |
public DateTime CreateTime { get; set; } = DateTime.Now; | |
public DateTime UpdateTime { get; set; } = DateTime.Now; | |
} | |
} |
# 特性注解
特性名称 | 特性作用 |
---|---|
[Key] | 用于标注实体模型中的主键 |
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] | 用于标注 Id 自增 |
🙂待更新…
# 一对一
# 一对多
# 多对多
# 搭建 DAL
▶️我们可以搭建一个通用的 DAL 层来进行数据访问。
using Microsoft.EntityFrameworkCore; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Threading.Tasks; | |
using WebCore.Models; | |
namespace WebCore.DAL | |
{ | |
public class BaseService<T> : IDisposable where T : BaseEntity | |
{ | |
private readonly CoreDbContext coreDb; | |
public BaseService(CoreDbContext coreDb) | |
{ | |
this.coreDb = coreDb; | |
} | |
public void Dispose() | |
{ | |
coreDb.Dispose(); | |
} | |
/// <summary> | |
/// 创建 | |
/// </summary> | |
/// <param name="t"></param> | |
/// <returns></returns> | |
protected async Task<bool> CreateAsync(T t) | |
{ | |
await coreDb.AddAsync<T>(t); | |
return coreDb.SaveChangesAsync().Result>0; | |
} | |
/// <summary> | |
/// 编辑 | |
/// </summary> | |
/// <param name="t"></param> | |
/// <returns></returns> | |
protected async Task<bool> EditAsync(T t) | |
{ | |
coreDb.Set<T>().Update(t); | |
return await coreDb.SaveChangesAsync()>0; | |
} | |
/// <summary> | |
/// 删除 | |
/// </summary> | |
/// <param name="t"></param> | |
/// <returns></returns> | |
protected async Task Remove(T t) | |
{ | |
coreDb.Remove<T>(t); | |
await coreDb.SaveChangesAsync(); | |
} | |
/// <summary> | |
/// 获得所有 | |
/// </summary> | |
/// <returns></returns> | |
protected IQueryable<T> GetAll(bool asc=true) | |
{ | |
if (asc) | |
{ | |
return coreDb.Set<T>().AsNoTracking().OrderBy(m=>m.CreateTime); | |
} | |
return coreDb.Set<T>().AsNoTracking(); | |
} | |
/// <summary> | |
/// 获得所有 | |
/// </summary> | |
/// <param name="expression"> 指定条件 & lt;/param> | |
/// <returns></returns> | |
protected IQueryable<T> GetAll(Expression<Func<T,bool>> expression,bool asc=true) | |
{ | |
return GetAll(asc).Where(expression); | |
} | |
/// <summary> | |
/// 获得所有并分页 | |
/// </summary> | |
/// <param name="expression"> 条件 & lt;/param> | |
/// <param name="pageSize"> 数量 & lt;/param> | |
/// <param name="pageIndex"> 页码 & lt;/param> | |
/// <param name="asc"> 排序 & lt;/param> | |
/// <returns></returns> | |
protected IQueryable<T> GetAllPage(Expression<Func<T, bool>> expression,int pageIndex , int pageSize=10, bool asc = true) | |
{ | |
return GetAll(asc).Where(expression).Skip(pageSize*pageIndex).Take(pageSize); | |
} | |
/// <summary> | |
/// 获得一个通过 id | |
/// </summary> | |
/// <param name="id"></param> | |
/// <returns></returns> | |
protected T GetOne(int id) | |
{ | |
return GetAll().FirstOrDefault(x => x.Id == id); | |
} | |
/// <summary> | |
/// 获得一个通过条件 | |
/// </summary> | |
/// <param name="expression"></param> | |
/// <returns></returns> | |
protected T GetOne(Expression<Func<T, bool>> expression) | |
{ | |
return GetAll().FirstOrDefault(expression); | |
} | |
} | |
} |