在 .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.mzph.cn/diannao/58743.shtml

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

相关文章

C++类和对象上

1. 类的定义 1.1 类定义格式 • class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员&#xff1a;类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。…

NineData云原生智能数据管理平台新功能发布|2024年10月版

10 月发布内容 本月发布 7 项更新&#xff0c;其中重点发布 2 项、功能优化 3 项、性能优化 1 项、其他发布 1 项。 重点发布​ 数据库 Devops - 数据生成​ NineData 支持在数据库中自动生成符合特定业务场景的随机数据&#xff0c;用于模拟实际生产环境中的数据情况&…

BGP路径属性与路由反射器

前言 IBGP水平分割规则用于防止AS内部产生环路&#xff0c;在很大程度上杜绝了IBGP路由产生环路的可能性&#xff0c;但是同时也带来了新的问题&#xff1a;BGP路由在AS内部只能传递一跳&#xff0c;如果建立IBGP对等体全互联模型又会加重设备的负担。 BGP 路径属性 AS_Path …

医学和生信web APP 平台- Appmatrix

医学&#xff08;和生信&#xff09;web APP 平台- Appmatrix 最近使用shinyproxy将平时所构建的shiny和streamlit医学类应用汇集在一起&#xff0c;实现一站式访问&#xff0c;另外&#xff0c;使用了自己电脑内网穿透&#xff0c;一定程度上缓解了数据分析类APP消耗计算资源…

Rust 力扣 - 1456. 定长子串中元音的最大数目

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们遍历长度为k的窗口&#xff0c;我们只需要记录窗口内的元音字母数量即可&#xff0c;遍历过程中刷新最大数目 题解代码 impl Solution {pub fn max_vowels(s: String, k: i32) -> i32 {let s s.as_byt…

Centos系统新增网卡后获取不到网卡的IP地址解决方法

一、问题描述 当我们给Centos系统添加了新的网卡后,使用查看IP地址命令【ip addr】时,发现新网卡没有获取到对应的IP地址信息,如下图所示: 二、解决方法 有两种解决方法:一种是自动获取IP地址;另外一种是手动配置IP地址; 2.1、自动获取IP地址 #自动获取网卡的IP地址命…

跨境卖家必备!好用的独立站建站工具推荐 !

对于跨境卖家来说&#xff0c;拥有一个独立站是拓展海外市场、提升品牌影响力的重要途径。而选择一款好用的独立站建站工具&#xff0c;则是成功搭建独立站的关键。 一、为什么跨境卖家需要独立站&#xff1f; 在跨境电商领域&#xff0c;独立站具有诸多优势。首先&#xff0c…

Windows Qt 6安装Oracle QOCI SQL Driver插件

本文参考 QOCI for the Oracle Call Interface (OCI)。 Windows 打开 Qt 6.8.0 (MSVC 2022 64-bit)。 Setting up environment for Qt usage… Remember to call vcvarsall.bat to complete environment setup! 执行 "D:\Program Files\Microsoft Visual Studio\2022\E…

书生实战营第四期-第二关python

一、任务1&#xff1a;完成Leetcode 383 1.代码 class Solution:def canConstruct(self,ransomNote: str, magazine: str) -> bool: # 创建一个字典来存储 magazine 中每个字符的出现次数 char_count {} # 遍历 magazine&#xff0c;统计每个字符的出现次数 for char…

计算机考研,选择西安交通大学还是哈工大?

C哥专业提供——计软考研院校选择分析专业课备考指南规划 经过全面分析&#xff0c;2025年考研西安交通大学和哈尔滨工业大学计算机专业的报考难度对比如下&#xff1a; 西安交通大学计算机专业 > 哈尔滨工业大学计算机专业 对于想要报考985高校计算机专业但核心目标是优…

CentOS系统查看CPU、内存、操作系统等信息

Linux系统提供了一系列命令可以用来查看系统硬件信息&#xff0c;如CPU的物理个数、核数、逻辑CPU数量、内存信息和操作系统版本。 查看物理CPU、核数和逻辑CPU 在多核、多线程的系统中&#xff0c;了解物理CPU个数、每个物理CPU的核数和逻辑CPU个数至关重要。超线程技术进一步…

项目升级到.Net8.0 Autofac引发诡异的问题

前两天把项目升级到.Net8.0了&#xff0c;把.Net框架升级了&#xff0c;其他一些第三方库升级了一部分&#xff0c;升级完以后项目跑不起来了&#xff0c;报如下错误&#xff1a; An unhandled exception occurred while processing the request. DependencyResolutionExcepti…

十八、【智能体】数据库:未来科技的大脑

在上一篇中我们讲到了 **变量 ** &#xff0c; 变量 的作用是保存用户个人信息&#xff0c;让 Bot记住用户的特征&#xff0c;使回复更加个性化。 上一篇内容为&#xff1a;https://blog.csdn.net/qq_40585384/article/details/143272599 但变量有一个缺点——存储的信息太单…

web文件包含include

php伪协议 在 PHP 中&#xff0c;伪协议&#xff08;Pseudo Protocols&#xff09; 也被称为 流包装器&#xff0c;这些伪协议以 php:// 开头&#xff0c;后面跟着一些参数&#xff0c;用于指定 要执行的操作 或 需要访问的资源。 伪协议表明这些协议并不是一个 真实的外部协议…

Diving into the STM32 HAL-----USART

如今&#xff0c;电子行业有许多串行通信协议和硬件接口可用。其中之一是通用同步/异步接收器/发射器接口&#xff0c;也简称为 USART。几乎每个微控制器都至少提供一个 UART 外设。几乎所有的 STM32 MCU 都提供至少两个 UART/USART 接口&#xff0c;但根据 MCU 封装支持的 I/O…

功能强大视频编辑软件 Movavi Video Editor Plus 2024 v24.2.0 中文特别版

Movavi Video Editor Plus中文修改版是一款功能强大的视频制作编辑软件&#xff0c;使用能够帮助用户快速从录制的素材中制作成一个精美的电影&#xff0c;支持进行视频剪辑&#xff0c;支持添加背影、音乐和各种音乐&#xff0c;软件使用简单&#xff0c;无需任何的经验和专业…

中国书画、

孙溟㠭浅析“古玺” “古玺”是秦以前印章的通称&#xff0c;远可追溯三代&#xff0c;兴盛于战国。古玺所用的文字是当时六国的篆书&#xff0c;也就是大篆&#xff0c;风格多种多样&#xff0c;变化不一&#xff0c;不容易认识。从文字形式上&#xff0c;可分阴文&#xff08…

WPF+MVVM案例实战(九)- 霓虹灯字效果控件封装实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、运行效果2、主菜单与界面实现1、主菜单2、霓虹灯字界面实现3、字体资源获取3、控件封装1.创建自定义控件2、依赖属性实现3、封装控件使用4、运行效果4、源代码获取1、运行效果 2、主菜单与界面实…

Python酷库之旅-第三方库Pandas(183)

目录 一、用法精讲 846、pandas.api.types.is_number函数 846-1、语法 846-2、参数 846-3、功能 846-4、返回值 846-5、说明 846-6、用法 846-6-1、数据准备 846-6-2、代码示例 846-6-3、结果输出 847、pandas.api.types.is_re函数 847-1、语法 847-2、参数 847…

【SSM详细教程】-13-SpringMVC详解

精品专题&#xff1a; 01.《C语言从不挂科到高绩点》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. 《SpringBoot详细教程》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12789841.html?spm1001.20…