二 EFCore (上) Crud 基础实现 . 【初体验,最简版code first + crud】

99 阅读2分钟

一 准备工作。

1.1 安装依赖项。

    <PackageReference Include="EntityFramework" Version="6.4.4" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.7" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.7">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.7" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.7">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.2" />

image.png

1.2 写DbContext 类,配置并注入.

//  Models/EFCoreDbContext.cs
using Microsoft.EntityFrameworkCore;
namespace Api.Models;

public class EFCoreDemoDbContext : DbContext
{
    //DbSet<UserInfo> userInfo { get; set; }
    public EFCoreDemoDbContext(DbContextOptions<EFCoreDemoDbContext> options)
        : base(options) { }
}
//appsettings.json 中写
  "ConnectionStrings": {
    "MySQLConnection": "server=localhost;port=3306;uid=root;pwd=123456;database=ef_demo"
  },
#region 注入DbContext
builder.Services.AddDbContext<EFCoreDemoDbContext>(opt => {
    string connectionString = builder.Configuration.GetConnectionString("MySQLConnection");
    var serverVersion = ServerVersion.AutoDetect(connectionString);
    opt.UseMySql(connectionString, serverVersion);
});
#endregion

二 实现Code First

2.1 学员实体

设计表,字段。

// Stu.cs
namespace Api.Models;

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

[Table("demo_stu")]
public class Stu
{
    [Column("id")]
    [MaxLength(11)]
    public int Id { get; set; }


    [Required]
    [Column("tname")]
    [MaxLength(32)]
    public string Name { get; set; }


    [Required]
    [Column("sn")]
    [MaxLength(32)]
    [Description("学号")]
    public string Sn { get; set; }


    [Column("remark")]
    [MaxLength(256)]
    public string Remark { get; set; }

    [Column("created_at")]
    [Description("创建时间")]
    public DateTime CreatedAt { get; set; }

    [Column("deleted_at")]
    public DateTime Deleted_at { get; set; }

}

在context 中加上

    DbSet<Stu> Stu { get; set; }

进入控制台。

   dotnet ef Migrations add Init
   
   dotnet ef database update

image.png

三 编写StuController 实现最简单的crud. (后续再折腾里面的细节)

控制器基础代码 ,注入

using Api.Models;
using Api.Models.Request;
using Mapster;
using Microsoft.AspNetCore.Mvc;

namespace Api.Controllers;

[ApiController]
public class StuController : Controller
{

    private readonly ILogger<StuController> _logger;

    EFCoreDemoDbContext _context;

    public StuController(ILogger<StuController> logger, EFCoreDemoDbContext context)
    {
        _logger = logger;
        _context=context;
    }
    //crud code
    ...

}

DTO 的定义。

//关联的请求结构。
namespace Api.Models.Request;

public class NewStuRequest
{
    public string Name { get; set; }
    public string? Sn { get; set; }
    public string? Remark { get; set; }

}

public class UpdateStuRequest
{
    public int Id { get; set; }
    public StuInput stu { get; set; }
}

public class StuInput
{
    public string Name { get; set; }
    public string? Sn { get; set; }
    public string? Remark { get; set; }
}

3.1 添加学员.

    [Route("api/stu/create")]
    [HttpPost]
    public  IActionResult CreateStu([FromBody] NewStuRequest request)
    {
        Stu stu = request.Adapt<Stu>();
        stu.CreatedAt = DateTime.Now;
        _context.Set<Stu>().Add(stu);
        _context.SaveChanges();
        return Ok(stu);
    }
    

save change 时,stu 会跟着一起改,得到对应的id . image.png

3.2 读数据。

(byId)

    [Route("api/stu/{id}")]
    [HttpGet]
    public async Task<IActionResult> GetStuByid(int id)
    {
        Stu? stu = _context.Set<Stu>().Find(id);
        return Ok(stu);
    }

image.png

读列表数据

    [Route("api/stu")]
    [HttpGet]
    public async Task<IActionResult> GetStuList()
    {
        List<Stu> stus = _context.Set<Stu>().Where( o => o.Id != 0 ).ToList();
        return Ok(stus);
    }

后续,进一步写,参数查询,分页等 。

3.3 更新

   [Route("api/stu/update")]
    [HttpPost]
    public async Task<IActionResult> UpdateStu([FromBody] UpdateStuRequest request)
    {

        // var  stu = request.stu.Adapt<Stu>();
        var stu = _context.Stu.FirstOrDefault(c => c.Id.Equals(request.Id));

        stu.Name = request.stu.Name;
        stu.Sn = request.stu.Sn;
        stu.Remark = request.stu.Remark;

        _context.Update(stu);
        _context.SaveChanges();
        return Ok(stu);
    }

3.4 删除


    [Route("api/stu/delete/{id}")]
    [HttpDelete]
    public async Task<IActionResult> Delete(int id)
    {
        var stu = _context.Stu.FirstOrDefault(c => c.Id.Equals(id));
        if (stu == null)
        {
            return BadRequest(new { count = -1, msg = "学员不存在,无法删除" });
        }
       _context.Stu.Remove(stu);
        int effectRows = _context.SaveChanges();

        if (effectRows >=0)
        {
            return Ok();
        }
        else {
            throw new Exception("删除失败");
        }
        return Ok();
    }

image.png

本篇仅实现的最简单的实现 。 距离成为项目 。(鉴权, 缓存,条件查询,翻页,逻辑删除,异步请求等问题) 后续章节细化处理。