在 .Net 8 WEBAPI 中实现实体框架的 Code First 方法

这是第一篇文章的延续。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

示例代码:https://download.csdn.net/download/hefeng_aspnet/91997370

介绍

在本文中,我们将讨论什么是 Entity Framework,以及如何在 .Net 8 项目中实现它。这是第一部分的延续,因此如果您是第一次阅读本文,请在继续阅读之前先查看第一部分。在本文中,我们将实现 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 方法使我们能够使用类创建模型和关系,然后基于这些类创建数据库。它使我们能够以面向对象的方式使用实体框架 (Entity Framework)。在这种方法中,您可以使用空数据库并添加表。

模型优先方法

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

数据库优先方法

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

先决条件

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

实施 EF8 的步骤

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

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

  1. Microsoft.EntityFrameworkCore
  2. Microsoft.EntityFrameworkCore.Design
  3. Microsoft.EntityFrameworkCore.Tools
  4. Microsoft.EntityFrameworkCore.SqlServer

**步骤 2.**在我们的项目中添加 OurHeroDbContext 文件。

  • 打开解决方案
  • 右键添加" Entity "文件夹
  • 添加 OurHeroDbContext 类(选择" Entity "文件夹并按Ctrl +Shift +A创建类)
  • 继承 DbContext 类
  • 添加构造函数并接受 EF 选项并发送到 DbContext
cs 复制代码
// OurHeroDbContext.cs
using Microsoft.EntityFrameworkCore;

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

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

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

cs 复制代码
// 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

bash 复制代码
"ConnectionStrings": {
  "OurHeroConnectionString": "Data Source=LAPTOP-4TSM9SDC;Initial Catalog=OurHeroDB; Integrated Security=true;TrustServerCertificate=True;"
}
bash 复制代码
//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 Server 作为数据库。因此我调用了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。

cs 复制代码
// 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>>

cs 复制代码
// 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 中。

更新方法返回类型。

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

任务<列表<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);

}

}

**步骤 9.**打开 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

});

}

}

}

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

下一个

Visual Studio

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

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

文件准备好后

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

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

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

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

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

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

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

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

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

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

概括

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

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
csdn_aspnet1 天前
.Net 8 Web API CRUD 操作
webapi·.net8
小虾爬滑丫爬1 天前
.net8发布Linux 版本程序,部署到Linux服务器上
linux·.net8·打包部署
小丫头呀24 天前
.NET8 通过自定义类映射appsettings.json 文件某个节点的配置
json·.net·.net8
csdn_aspnet1 个月前
使用 Entity Framework Code First 方法创建 ASP.NET Core 5.0 Web API
.netcore·webapi
yswenli2 个月前
使用Cyclops.PdfKit根据pdf模板生成pdf文件
docker·pdf·.net8
SabreWulf20202 个月前
Ubuntu 20.04手动安装.NET 8 SDK
linux·ubuntu·avalonia·.net8
csdn_aspnet2 个月前
在 ASP.NET 8 WebAPI 中使用不同的提供程序验证多个令牌(Token)及常见问题解答
token·.net8
csdn_aspnet2 个月前
.NET 8 集成 JWT Bearer Token
jwt·.net8
wstcl3 个月前
安卓app、微信小程序等访问多个api时等待提示调用与关闭问题
android·微信小程序·webapi