在 .NET 8 Web API 中实现 Entity Framework 的 Code First 方法

news2024/11/7 11:39:21

本次介绍分为3篇文章: 

1:.Net 8 Web API CRUD 操作
.Net 8 Web API CRUD 操作-CSDN博客

2:在 .Net 8 API 中实现 Entity Framework 的 Code First 方法
https://blog.csdn.net/hefeng_aspnet/article/details/143229912

3:.NET 8 Web API 中的身份验证和授权
https://blog.csdn.net/hefeng_aspnet/article/details/143231987 

参考文章:

1:Dot Net 8 Web API CRUD 操作
https://medium.com/@codewithankitsahu/net-8-web-api-crud-operations-125bb3083113

2:在 .Net 8 API 中实现 Entity Framework 的 Code First 方法
https://medium.com/@codewithankitsahu/implement-entity-framework-a-code-first-approach-in-net-8-api-80b06d219373

3:.NET 8 Web API 中的身份验证和授权
https://medium.com/@codewithankitsahu/authentication-and-authorization-in-net-8-web-api-94dda49516ee

这是前一篇文章得部分的延续。 

介绍
        在本文中,我们将讨论什么是实体框架以及如何在 .Net 8 项目中实现它。这是前一篇文章部分的延续,因此如果您是本文的新手,请在继续阅读之前查看我的第 1 部分。在本文中,我们将实现 EF8 代码优先方法。

什么是实体框架?
        · 实体框架 (EF) 是一个对象关系映射器,使 .NET 开发人员能够使用特定于域的对象处理关系数据。
        · 它消除了开发人员通常需要编写的大部分数据访问代码。
        · 其目的是将关系抽象到关系数据库。

为什么选择实体框架?
        Entity Framework 是一个 ORM,ORM 旨在通过减少持久保存应用程序中使用的数据的冗余任务来提高开发人员的工作效率。

实体框架的功能
        · Entity Framework 是一种轻量级、可扩展的对象关系映射 (ORM) 技术。
        · Entity Framework 支持 Windows、Linux 和 macOS 等多种平台。
        · 实体框架支持关系数据源和非关系数据源。
        · Entity Framework 可与 SQL Server、SQL Server Compact、SQLite 和 PostgreSQL 等广泛使用的数据库有效协作。
        · Entity Framework 通过支持数据库,让程序员能够更轻松地执行创建、读取、更新和删除 (CRUD) 操作。它还通过保留内存表,让开发人员能够更轻松地执行单元测试。

实体框架开发方法
        创建实体框架有三种方法。

代码优先方法
        Code First 方法使我们能够使用类创建模型和关系,然后从这些类创建数据库。它使我们能够以面向对象的方式使用实体框架。在这种方法中,您可以使用空数据库并添加表。

模型优先方法
        在这种方法中,首先使用 ORM 设计器创建模型类及其关系,然后使用此模型生成物理数据库。模型优先方法意味着我们创建实体和关系的图表,然后将其自动转换为代码模型。

数据库优先方法
        数据库优先方法使我们能够从现有数据库创建实体模型。这种方法有助于我们减少需要编写的代码量。以下步骤将使用数据库优先方法创建实体模型。

先决条件

Visual Studio 2022(任何版本 - 社区版 / 专业版 / 企业版)
Microsoft SQL Server 2008 或更高版本。
.Net Core 8 SDK 或更高版本

实施 EF8 需遵循的步骤

        步骤1.从NuGet安装实体框架包。

右键单击您的项目 -> 单击“管理 NuGet 包” -> 打开“浏览”选项卡 -> 在下方搜索 EF8 包

Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.SqlServer

第 2 步:在我们的项目中添加 OurHeroDbContext 文件。

  • 打开解决方案
  • 右键点击并添加“ Entity ”文件夹
  • 添加 OurHeroDbContext 类(选择“ Entity ”文件夹并按Ctrl +Shift +A创建类)
  • 继承 DbContext 类
  • 添加构造函数并接受 EF 选项并发送到 DbContext

// OurHeroDbContext.cs
using Microsoft.EntityFrameworkCore;

namespace DotNet8WebAPI.Entity
{
    public class OurHeroDbContext : DbContext
    {
        public OurHeroDbContext(DbContextOptions<OurHeroDbContext> options) : base(options)
        {
        }
    }
}

步骤3.在OurHeroDbContext文件中注册DB模型。

配置我们的 EF 模型并加载预定义数据(主数据)。

// OurHeroDbContext.cs
using DotNet8WebAPI.Model;
using Microsoft.EntityFrameworkCore;

namespace DotNet8WebAPI.Entity
{
    public class OurHeroDbContext : DbContext
    {
        public OurHeroDbContext(DbContextOptions<OurHeroDbContext> options) : base(options)
        {
        }
        // Registered DB Model in OurHeroDbContext file
        public DbSet<OurHero> OurHeros { get; set; }

        /*
         OnModelCreating mainly used to configured our EF model
         And insert master data if required
        */
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Setting a primary key in OurHero model
            modelBuilder.Entity<OurHero>().HasKey(x => x.Id);

            // Inserting record in OurHero table
            modelBuilder.Entity<OurHero>().HasData(
                new OurHero
                {
                    Id = 1,
                    FirstName = "System",
                    LastName = "",
                    isActive = true,
                }
            );
        }
    }
}

步骤 4.在 appsettings.json 文件中添加 ConnectionStrings 

"ConnectionStrings": {
"OurHeroConnectionString": "Data Source=LAPTOP-4TSM9SDC;Initial Catalog=OurHeroDB; Integrated Security=true;TrustServerCertificate=True;"

//appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"OurHeroConnectionString": "Data Source=LAPTOP-4TSM9SDC;Initial Catalog=OurHeroDB; Integrated Security=true;TrustServerCertificate=True;"
},
"AllowedHosts": "*"

步骤 5.注册 DbContext

选择您的数据库 — 我使用 SQL 服务器作为数据库。这就是我调用UseSqlServer方法的原因。

提供 ConnectionString

//*********************** Register DbContext and provide ConnectionString .***********************
builder.Services.AddDbContext<OurHeroDbContext>(db => db.UseSqlServer(builder.Configuration.GetConnectionString("OurHeroConnectionString")), ServiceLifetime.Singleton);
//*********************** Register DbContext end.***********************  

// Program.cs

using DotNet8WebAPI.Entity;
using DotNet8WebAPI.Services;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

//*********************** Add services to the container.***********************
builder.Services.AddTransient<IOurHeroService, OurHeroService>();
//*********************** Add services to the container end.***********************

//*********************** Register DbContext and provide ConnectionString .***********************
builder.Services.AddDbContext<OurHeroDbContext>(db => db.UseSqlServer(builder.Configuration.GetConnectionString("OurHeroConnectionString")), ServiceLifetime.Singleton);
//*********************** Register DbContext end.***********************

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run(); 

第 6 步。转到 OurHeroService 并在构造函数中注入我们的 OurHeroDbContext。 

// OurHeroService.cs

using DotNet8WebAPI.Entity;
using DotNet8WebAPI.Model;

namespace DotNet8WebAPI.Services
{
    public class OurHeroService : IOurHeroService
    {
        private readonly OurHeroDbContext _db;
        public OurHeroService(OurHeroDbContext db)
        {
            _db = db;
        }
    }
}

步骤 7.现在使用数据库上下文而不是内存集合来获取 OurHeros 记录。

使用 async-await 异步获取 OurHeros 记录。

而不是返回痛苦对象作为 Task<List<OurHero>> 返回

列表<OurHero> → 任务<列表<OurHero>>

// OurHeroService.cs

using DotNet8WebAPI.Entity;
using DotNet8WebAPI.Model;
using Microsoft.EntityFrameworkCore;

namespace DotNet8WebAPI.Services
{
    public class OurHeroService : IOurHeroService
    {
        private readonly OurHeroDbContext _db;
        public OurHeroService(OurHeroDbContext db)
        {
            _db = db;
        }

        public async Task<List<OurHero>> GetAllHeros(bool? isActive)
        {
            if (isActive == null) { return await _db.OurHeros.ToListAsync(); }

            return await _db.OurHeros.Where(obj => obj.isActive == isActive).ToListAsync();
        }

        public async Task<OurHero?> GetHerosByID(int id)
        {
            return await _db.OurHeros.FirstOrDefaultAsync(hero => hero.Id == id);
        }

        public async Task<OurHero?> AddOurHero(AddUpdateOurHero obj)
        {
            var addHero = new OurHero()
            {
                FirstName = obj.FirstName,
                LastName = obj.LastName,
                isActive = obj.isActive,
            };

            _db.OurHeros.Add(addHero);
            var result = await _db.SaveChangesAsync();
            return result >= 0 ? addHero : null;
        }

        public async Task<OurHero?> UpdateOurHero(int id, AddUpdateOurHero obj)
        {
            var hero = await _db.OurHeros.FirstOrDefaultAsync(index => index.Id == id);
            if (hero != null)
            {
                hero.FirstName = obj.FirstName;
                hero.LastName = obj.LastName;
                hero.isActive = obj.isActive;

                var result = await _db.SaveChangesAsync();
                return result >= 0 ? hero : null;
            }
            return null;
        }

        public async Task<bool> DeleteHerosByID(int id)
        {
            var hero = await _db.OurHeros.FirstOrDefaultAsync(index => index.Id == id);
            if (hero != null)
            {
                _db.OurHeros.Remove(hero);
                var result = await _db.SaveChangesAsync();
                return result >= 0;
            }
            return false;
        }
    }
}

步骤 8.在 IOurHeroService 中。

更新方法返回类型。

作为任务返回,而不是普通的类模型。

Task<List<OurHero>> GetAllHeros(bool? isActive);

// IOurHeroService.cs
using DotNet8WebAPI.Model;

namespace DotNet8WebAPI.Services
{
    public interface IOurHeroService
    {
        Task<List<OurHero>> GetAllHeros(bool? isActive);
        Task<OurHero?> GetHerosByID(int id);
        Task<OurHero?> AddOurHero(AddUpdateOurHero obj);
        Task<OurHero?> UpdateOurHero(int id, AddUpdateOurHero obj);
        Task<bool> DeleteHerosByID(int id);
    }
}

第九步:打开 OurHeroController 文件。

在所有操作方法中实现 async-await,因为现在我们的 IOurHeroService 异步返回响应。

[HttpGet]
public 
async Task<IActionResult> Get([FromQuery] bool? isActive = null)
{
var heros = 
await _heroService.GetAllHeros(isActive);
return Ok(heros);
}
 

// OurHeroController.cs
using DotNet8WebAPI.Model;
using DotNet8WebAPI.Services;
using Microsoft.AspNetCore.Mvc;

namespace DotNet8WebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class OurHeroController : ControllerBase
    {
        private readonly IOurHeroService _heroService;
        public OurHeroController(IOurHeroService heroService)
        {
            _heroService = heroService;
        }

        [HttpGet]
        public async Task<IActionResult> Get([FromQuery] bool? isActive = null)
        {
            var heros = await _heroService.GetAllHeros(isActive);
            return Ok(heros);
        }

        [HttpGet("{id}")]
        //[Route("{id}")] // /api/OurHero/:id
        public async Task<IActionResult> Get(int id)
        {
            var hero = await _heroService.GetHerosByID(id);
            if (hero == null)
            {
                return NotFound();
            }
            return Ok(hero);
        }

        [HttpPost]
        public async Task<IActionResult> Post([FromBody] AddUpdateOurHero heroObject)
        {
            var hero = await _heroService.AddOurHero(heroObject);

            if (hero == null)
            {
                return BadRequest();
            }

            return Ok(new
            {
                message = "Super Hero Created Successfully!!!",
                id = hero!.Id
            });
        }

        [HttpPut]
        [Route("{id}")]
        public async Task<IActionResult> Put([FromRoute] int id, [FromBody] AddUpdateOurHero heroObject)
        {
            var hero = await _heroService.UpdateOurHero(id, heroObject);
            if (hero == null)
            {
                return NotFound();
            }

            return Ok(new
            {
                message = "Super Hero Updated Successfully!!!",
                id = hero!.Id
            });
        }

        [HttpDelete]
        [Route("{id}")]
        public async Task<IActionResult> Delete([FromRoute] int id)
        {
            if (!await _heroService.DeleteHerosByID(id))
            {
                return NotFound();
            }

            return Ok(new
            {
                message = "Super Hero Deleted Successfully!!!",
                id = id
            });
        }
    }
}

第十步。现在,我们的实体框架集成几乎已准备就绪。

下一个

Visual Studio

  • 打开“工具”菜单(位于 Visual Studio 工具栏中)
  • 选择 NuGet 包管理器
  • 然后选择包管理器控制台

运行add-migration [name]命令,生成DB迁移文件。

文件准备好后

然后,运行update-database命令来反映数据库端的迁移变化。

运行update-database命令后。如果您也收到相同的错误。

全球化不变模式仅支持不变文化。

然后按照以下步骤解决该问题。

  • 打开解决方案资源管理器
  • 双击您的项目
  • 它将打开.csproj文件
  • 将InvariantGlobalization设置从 true更新为false(可在 PropertyGroup 部分中找到)
  • 保存.csproj文件
  • 再次运行update-database命令

一旦更新的数据库 成功运行,您将像这样在 SQL Server 中验证您的数据库。

步骤11.现在我们的实体框架已经成功实现。

我们可以运行我们的应用程序并验证。

目前,我们有一个条目,因为我们是使用 OnModelCreating 方法插入的。

现在,我将使用 post-API (/api/OurHero)插入另一个条目

概括
        就这样!您已经创建了一个完整的 .NET 8 Web API,用于使用 SQL Server 数据库进行 CRUD 操作。现在您可以将此 API 集成到您的前端应用程序中。 

 第3篇:.NET 8 Web API 中的身份验证和授权
https://blog.csdn.net/hefeng_aspnet/article/details/143231987 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2229664.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初识动态规划(由浅入深)

&#x1f913; 动态规划入门与进阶指南 &#x1f4d8; 动态规划&#xff08;Dynamic Programming, DP&#xff09;是一种非常经典的&#x1f4d0;算法方法&#xff0c;特别适合用来解决那些有大量重复计算的问题&#x1f300;。它可以将复杂的问题拆分为小问题&#x1f9e9;&a…

【STM32】SD卡

(一)常用卡的认识 在学习这个内容之前&#xff0c;作为生活小白的我对于SD卡、TF卡、SIM卡毫无了解&#xff0c;晕头转向。 SD卡&#xff1a;Secure Digital Card的英文缩写&#xff0c;直译就是“安全数字卡”。一般用于大一些的电子设备比如&#xff1a;电脑、数码相机、AV…

《JVM第5课》虚拟机栈

无痛快速学习入门JVM&#xff0c;欢迎订阅本免费专栏 Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xff0c;简称JVM栈&#xff0c;又称Java方法栈&#xff09;是 JVM 运行时数据区的一部分&#xff0c;主要用于支持Java方法的执行。每当一个新线程被创建时&#xf…

Java Executor RunnableScheduledFuture 总结

前言 相关系列 《Java & Executor & 目录》《Java & Executor & RunnableScheduledFuture & 源码》《Java & Executor & RunnableScheduledFuture & 总结》《Java & Executor & RunnableScheduledFuture & 问题》 涉及内容 《…

软考(中级-软件设计师)数据库篇(1101)

第6章 数据库系统基础知识 一、基本概念 1、数据库 数据库&#xff08;Database &#xff0c;DB&#xff09;是指长期存储在计算机内的、有组织的、可共享的数据集合。数据库中的数据按一定的数据模型组织、描述和存储&#xff0c;具有较小的冗余度、较高的数据独立性和扩展…

zynq PS端跑Linux响应中断

这篇文章主要是讲述如何在Zynq的PS上跑Linux启动IRQ&#xff0c;环境为vivado2019.1&#xff0c;petalinux2019.1 ubuntu20.04&#xff0c;本人初学者&#xff0c;欢迎批评指正 1. Vivado硬件设计 确保自定义IP的中断信号通过 IRQ_F2P 连接到PS端。在开始Petalinux配置之前&a…

R语言贝叶斯

原文链接&#xff1a;R语言贝叶斯进阶&#xff1a;INLA下的贝叶斯回归、生存分析、随机游走、广义可加模型、极端数据的贝叶斯分析https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247625527&idx8&snba4e50376befd94022519152609ee8d0&chksmfa8daad0cdfa…

qt QRadioButton详解

QRadioButton 是一个可以切换选中&#xff08;checked&#xff09;或未选中&#xff08;unchecked&#xff09;状态的选项按钮。单选按钮通常呈现给用户一个“多选一”的选择&#xff0c;即在一组单选按钮中&#xff0c;一次只能选中一个按钮。 重要方法 QRadioButton(QWidget…

webm格式怎么转换成mp4?这9种转换方法你肯定能够学会!

webm格式怎么转换成mp4&#xff1f;WebM&#xff0c;作为一种新兴的视频文件格式&#xff0c;虽然带着革新性的光芒&#xff0c;在视频压缩效率和播放流畅性上表现出色&#xff0c;却也面临着几个重要的挑战&#xff0c;这些问题直接影响了用户的体验&#xff0c;首先&#xff…

HTML 语法规范全解:构建清晰、兼容性强的网页基础

文章目录 一、代码注释1.1 使用注释的主要目的1.2 使用建议二、标签的使用2.1 开始标签和结束标签2.2 自闭合标签2.3 标签的嵌套2.4 标签的有效性三、属性四、缩进与格式4.1 一致的缩进4.2 元素单独占用一行4.3 嵌套元素的缩进4.4 避免冗长的行五、字符编码六、小结在开发 HTML…

10 P1094 [NOIP2007 普及组] 纪念品分组

题目&#xff1a; 代码&#xff1a; #include<iostream> using namespace std; # define M 100 #include<algorithm> int sa[100005];int main() {int w,n;cin>>w>>n;for(int i1;i<n;i){cin>>sa[i];}sort(sa1,sa1n);int l1;int rn;int count…

LeetCode.冗余连接(并查集以及广度优先搜索)

684.冗余连接| 传送门&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 树可以看成是一个连通且 无环 的 无向 图。 给定往一棵 n 个节点 (节点值 1&#xff5e;n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1 到 n 中间&#xff0c;且这条附加的边不属于树中…

一文彻底整明白,基于Ollama工具的LLM大语言模型Web可视化对话机器人部署指南

在上一篇博文中&#xff0c;我们在本地部署了Llama 3 8B参数大模型&#xff0c;并用 Python 写了一个控制台对话客户端&#xff0c;基本能愉快的与 Llama 大模型对话聊天了。但控制台总归太技术化&#xff0c;体验不是很友好&#xff0c;我们希望能有个类似 ChatGPT 那样的 Web…

BES2600WM---HiLink RM56 EVK

0 Preface/Foreword 1 环境搭建 1.1 安装依赖工具 sudo apt-get install build-essential gcc g make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-boot-tools mtd-utils…

Leetcode21:合并两个有效链表

原题地址&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示…

51c嵌入式~IO合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/12383193 一、单片机通信数据接收解析方法 前阵子一朋友使用单片机与某外设进行通信时&#xff0c;外设返回的是一堆格式如下的数据&#xff1a; AA AA 04 80 02 00 02 7B AA AA 04 80 02 00 08 75 AA AA 04 80 02 00 9B E2…

java或c#是如何对数据库的表字段加密的处理的?

对于表格数据的加密处理&#xff0c;通常涉及到对数据库中存储的数据进行加密&#xff0c;以保护敏感信息。 Java示例&#xff08;使用AES算法加密数据库表数据&#xff09; 首先&#xff0c;你需要一个数据库连接&#xff0c;这里假设你使用的是JDBC连接MySQL数据库。以下是…

Android Studio Dolphin 下载、安装与配置教程

文章目录 Android Studio Dolphin简介一、核心特性二、新增功能三、用户体验优化 一&#xff0c;下载百度网盘迅雷云盘 二&#xff0c;安装三&#xff0c;下载组件四&#xff0c;添加SDK五&#xff0c;创建项目六&#xff0c;安装 Device模拟器运行项目 Android Studio Dolphin…

java开发等一些问题,持续更新

微服务和单服务的区别 微服务&#xff08;Microservices&#xff09;和单体服务&#xff08;Monolithic Architecture&#xff09;是两种不同的软件架构风格&#xff0c;各有其特点和适用场景。 微服务架构&#xff1a; 模块化&#xff1a; 微服务架构将应用程序分解为一系列小…

全国分省灵活就业情况数据集(2015-2019年)

数据简介&#xff1a;就业是民生之本&#xff0c;是“六稳”“六保”之首&#xff0c;对于拥有14亿人口的中国而言&#xff0c;就业问题至关重要。“十四五”规划建议中指出&#xff0c;应强化就业优先政策&#xff0c;千方百计稳定和扩大就业&#xff0c;实现更充分更高质量就…