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

本次介绍分为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.rhkb.cn/news/460956.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

斐波那契时间序列,精准捕捉市场拐点 MT4免费公式源码!

指标名称&#xff1a;斐波那契时间序列 版本&#xff1a;MT4 ver. 2.01 斐波那契时间序列是一种技术分析工具&#xff0c;通过将斐波那契数列&#xff08;如1, 2, 3, 5, 8, 13等&#xff09;应用于时间轴上&#xff0c;用于预测市场价格的时间周期拐点。斐波那契时间序列在股…

Unsafe Fileupload-pikachu

系列目录 第一章 暴力破解 第二章 Cross-Site Scripting-pikachu 第三章 CSRF 第四章 sql-injection 第五章 RCE 第六章 File inclusion 第七章 Unsafe filedownload 第八章 Unsafe fileupload 概述 不安全的文件上传漏洞概述 文件上传功能在web应用系统很常见&#x…

嵌入式学习-网络-Day05

嵌入式学习-网络-Day05 1.网络超时检测 1.1应用场景 1.2设置超时检测 1&#xff09;通过参数设置 2&#xff09;setsockopt属性设置 3&#xff09;定时器alarm设置 2.广播 2.1广播发送流程&#xff1a; 2.2广播接收流程&#xff1a; 3.组播 3.1组播发送流程 3.2组播接收流程 4.…

Android启动流程_SystemServer阶段

前言 上一篇文档我们描述了在 Android 启动流程中 Zygote 部分的内容&#xff0c;从 Zygote 的配置、启动、初始化等内容展开&#xff0c;描述了 Zygote 在 Android 启动中的功能逻辑。本篇文档将会继续 Android 启动流程的描述&#xff0c;从 SystemServer 进程的内容展开&am…

一年期免费HTTPS证书:网络安全新选择

HTTPS证书的重要性 HTTPS证书&#xff0c;全称为安全套接字层/传输层安全协议证书&#xff0c;是一种在互联网上建立安全连接的数字证书。它通过公钥加密技术&#xff0c;对网站和用户之间的数据传输进行加密&#xff0c;有效防止数据被窃取或篡改&#xff0c;保障用户信息的安…

(实战)WebApi第10讲:Swagger配置、RESTful与路由重载

一、Swagger配置 1、导入SwashBuckle.AspNetCore包 2、在.NET Core 5框架里的startup.cs文件里配置swagger 3、在.NET Core 6框架里的Program.cs文件里配置swagger 二、RESTful风格&#xff1a;路由重载&#xff0c;HttpGet()括号中加参数 &#xff08;1&#xff09;原则&…

Pr 视频效果:闪光灯

视频效果/风格化/闪光灯 Stylize/Strobe Light 闪光灯 Strobe Light效果可用于在视频中创建闪烁或频闪的效果&#xff0c;类似于舞台上的频闪灯或摄影中的闪光灯。 ◆ ◆ ◆ 效果选项说明 通过调整各种参数&#xff0c;可以自定义闪光的颜色、频率、持续时间和混合模式&#…

Spring自动装配(特别版)

今天整理了一下Spring自动装配的过程,也突出了几个比较难以解答的问题.实践来求真知. 一. 自动装配过程 先按类型查找,若只有一个则直接返回如果找到多个,则匹配名字如果名字不一致,则报错. 二. 自动装配方式 构造器注入(推荐): 因为如果有一天脱离了Spring的环境,我们去使用…

力扣之612.平面上的最近距离

文章目录 1. 612.平面上的最近距离1.1 题目说明1.2 准备数据1.3 解法1.4 结果截图 1. 612.平面上的最近距离 1.1 题目说明 Point2D 表&#xff1a; ----------------- | Column Name | Type | ----------------- | x | int | | y | int | ----------------- (x, y) 是该表的…

Mac下载 安装MIMIC-IV 3.0数据集

参考blog MIMIC IV 3.0数据库安装方法_mimic数据下载-CSDN博客 MIMIC IV数据库安装&#xff08;二&#xff09;_mimic数据库安装-CSDN博客 MIMIC-IV3.0安装_mimic iv 3.0-CSDN博客 MIMIC-IV-v2.0安装教程_mimic iv 安装教程-CSDN博客 MIMIC IV 3.0数据库安装方法或者思路&…

java项目之教师工作量管理系统源码(springboot)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的教师工作量管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 教师工作量管理系统的…

12. MapReduce全局计数器

一. 计数器概述 在执行MapReduce程序时&#xff0c;控制台的输出中一般会包含如下内容。 这些输出就是MapReduce的全局计数器的输出信息。计数器是用来记录job的执行进度和状态的&#xff0c;它的作用可以理解为日志&#xff0c;方便用户了解任务的执行状况&#xff0c;辅助…

STM32F103C8T6 IO 操作

1.开启相关时钟 在 STM32 微控制器中&#xff0c;开启 GPIO 端口的时钟是确保 IO 口可以正常工作的第一步。 查找 RCC 寄存器使能时钟 在 STM32 中&#xff0c;时钟控制的寄存器通常位于 RCC (Reset and Clock Control) 模块中。不同的 STM32 系列&#xff08;如 STM32F1、STM…

使用LangChain控制大模型的输出——解析器Parser

LangChain框架中有两个好用的工具&#xff1a; 提示词模板(PromptTemplate)用于指定LLM的输入&#xff0c;解析器(Parser)来正确解释LLM给出的输出 即&#xff1a; 提示词模板(PromptTemplate)&#xff1a;用于格式化地接受输入string变量&#xff0c;作为完整的提示词。 如 给…

架构的本质之 MVC 架构

前言 程序员习惯的编程方式就是三步曲。 所以&#xff0c;为了不至于让一个类撑到爆&#x1f4a5;&#xff0c;需要把黄色的对象、绿色的方法、红色的接口&#xff0c;都分配到不同的包结构下。这就是你编码人生中所接触到的第一个解耦操作。 分层框架 MVC 是一种非常常见且常…

VScode + PlatformIO 了解

​Visual Studio Code Visual Studio Code&#xff08;简称 VS Code&#xff09;是一款由微软开发且跨平台的免费源代码编辑器。该软件以扩展的方式支持语法高亮、代码自动补全&#xff08;又称 IntelliSense&#xff09;、代码重构功能&#xff0c;并且内置了工具和 Git 版本…

微信公众号(或微信浏览器)获取openId(网页授权)

下单支付需要openId 首先授权去拿到code --然后调用后太换取openId 1.去拿取code 下图中执行到window.location.href &#xff08; redirect_uri 传入当前路径-&#xff09;–执行后重新跳转到当前页面–但是路径上会带上code参数 //然后调用后台方法–将code传给后台得到 o…

Steam deck 倒腾日记 - 安装Windows软件,玩上黑神话悟空

Steam deck 倒腾日记 关于Steam Deck基本信息性能特点游戏兼容性 问题一: 软键盘输入问题二: 系统切换问题三: 安装运行Window 软件关于Proton如何运行 问题四: 优化网络问题黑神话.悟空PS参考 关于Steam Deck Steam Deck是一款由Valve开发的便携式游戏PC&#xff0c;它搭载了A…

人工智能的前世今生:从幻想走向现实

在科技飞速发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经成为我们生活中不可或缺的一部分。从智能手机的语音助手到自动驾驶汽车&#xff0c;AI的应用无处不在。但是&#xff0c;人工智能的发展历程并非一帆风顺&#xff0c;它经历了从兴起、寒冬到复兴的曲折…

ARM base instruction -- bfc

Bitfield Clear sets a bitfield of <width> bits at bit position <lsb> of the destination register to zero, leaving the other destination bits unchanged. 位域清除将目标寄存器位位置<lsb>处<width>位的位域设置为零&#xff0c;而保留其他目…