使用 .NET C# 创建带分页 API

作者:微信公众号:【架构师老卢】
8-3 18:1
39

概述:将较大的内容拆分为不同的页面称为分页。这种方法大大增强了用户体验并加快了网页的加载速度。此示例将演示如何使用 .NET 创建分页 API,并将 MySQL 用作数据库。先决条件.NET 8MySQL的设置项目dotnet new webapi -o dotnet_api -n App创建一个名为“example”的测试数据库,并运行database.sql文件以导入表和数据。项目结构├─ Controllers │  └─ ProductController.cs ├─ Models │  ├─ DataContext.cs │  └─ Product.cs ├─ wwwroot

将较大的内容拆分为不同的页面称为分页。这种方法大大增强了用户体验并加快了网页的加载速度。此示例将演示如何使用 .NET 创建分页 API,并将 MySQL 用作数据库。

先决条件

  • .NET 8
  • MySQL的

设置项目

dotnet new webapi -o dotnet_api -n App

创建一个名为“example”的测试数据库,并运行database.sql文件以导入表和数据。

项目结构

├─ Controllers  
│  └─ ProductController.cs  
├─ Models  
│  ├─ DataContext.cs  
│  └─ Product.cs  
├─ wwwroot  
│  └─ index.html  
├─ Util.cs  
├─ Program.cs  
├─ App.csproj  
└─ appsettings.json

项目文件

App.csproj

此文件是 .NET 项目配置文件。我们在此处添加了包。MySql.EntityFrameworkCore

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="MySql.EntityFrameworkCore" Version="8.0.0" />
    </ItemGroup>
</Project>

appsettings.json

这是包含数据库连接信息的 .NET 应用程序配置文件。

{  
    "Logging": {  
        "LogLevel": {  
            "Default": "Warning"  
        }  
    },  
    "AllowedHosts": "*",  
    "ConnectionStrings": {  
        "Database": "server=localhost;port=3306;database=example;user id=root;password=;"  
    }  
}

Program.cs

此文件是 .NET API 应用程序的主要入口点。

using Microsoft.EntityFrameworkCore;  
  
var builder = WebApplication.CreateBuilder(args);  
builder.Services.AddControllers();  
builder.Services.AddDbContext<App.Models.DataContext>(options => options.UseMySQL(builder.Configuration.GetConnectionString("Database")));  
var app = builder.Build();  
app.UseDefaultFiles();  
app.UseStaticFiles();  
app.UseRouting();  
app.MapControllers();  
app.Run();
  • app.UseDefaultFiles()使用 index.html 作为默认 HTML 文件。
  • app.UseStaticFiles()提供文件夹 wwwroot 中的静态文件。

Util.cs

此文件定义了类的扩展方法,用于实现实体框架的动态列排序。OrderBy()IQueryable

using System.Linq.Expressions;  
using System.Reflection;  
  
namespace App  
{  
    public static class Util  
    {  
        public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> query, string column, string direction)  
        {  
            var type = typeof(TEntity);  
            var parameter = Expression.Parameter(type);  
            var property = type.GetProperty(column, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);  
            var member = Expression.MakeMemberAccess(parameter, property);  
            var lamda = Expression.Lambda(member, parameter);  
            var method = direction == "desc" ? "OrderByDescending" : "OrderBy";  
            var expression = Expression.Call(typeof(Queryable), method, new Type[] { type, property.PropertyType }, query.Expression, Expression.Quote(lamda));  
            return query.Provider.CreateQuery<TEntity>(expression);  
        }  
    }  
}

DataContext.cs

在 .NET 应用程序中使用实体框架 (EF) 时,这是必需的文件。它用于将数据库中的表和列信息映射到实体。

using Microsoft.EntityFrameworkCore;  
  
namespace App.Models  
{  
    public partial class DataContext : DbContext  
    {  
        public virtual DbSet<Product> Product { get; set; }  
  
        public DataContext()  
        {  
        }  
  
        public DataContext(DbContextOptions<DataContext> options) : base(options)  
        {  
        }  
          
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)  
        {  
        }  
  
        protected override void OnModelCreating(ModelBuilder modelBuilder)  
        {  
            modelBuilder.Entity<Product>(entity =>  
            {  
                entity.ToTable("Product");  
                entity.HasKey(e => e.Id);  
                entity.Property(e => e.Id).HasColumnName("id");  
                entity.Property(e => e.Name).HasColumnName("name").HasMaxLength(50).IsUnicode(false);  
                entity.Property(e => e.Price).HasColumnName("price").HasColumnType("decimal(12,2)");  
            });  
        }  
    }  
}

Product.cs

此文件定义映射到名为“Product”的数据库表的模型信息。

using System.ComponentModel.DataAnnotations;  
  
namespace App.Models  
{  
    public partial class Product  
    {  
        [Key]  
        public int Id { get; set; }  
        public string Name { get; set; }  
        public decimal Price { get; set; }  
    }  
}

ProductController.cs

此文件用于处理传入的请求并为客户端生成分页数据。

using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using App.Models;

namespace App.Controllers
{
    public class ProductController : Controller
    {
        private readonly DataContext _context;

        public ProductController(DataContext context)
        {
            _context = context;
        }

        [HttpGet("api/products")]
        public async Task<IActionResult> Index()
        {
            int page = Request.Query["page"].Any() ? Convert.ToInt32(Request.Query["page"]) : 1;
            int size = Request.Query["size"].Any() ? Convert.ToInt32(Request.Query["size"]) : 10;
            string order = Request.Query["order"].Any() ? Request.Query["order"].First() : "Id";
            string direction = Request.Query["direction"].Any() ? Request.Query["direction"].First() : "asc";
            var query = _context.Product.Select(e => new {
                Id = e.Id,
                Name = e.Name,
                Price = e.Price
            });
            query = query.OrderBy(order, direction);
            var products = await query.Skip((page - 1) * size).Take(size).ToListAsync();
            return Ok(products);
        }
    }
}
  • 我们利用查询字符串通过该方法获取和创建分页数据。page, size, order, directionquery.Skip((page - 1) * size).Take(size)
  • 我们使用 Util.cs 文件中定义的扩展方法来对对象执行排序。OrderBy()IQueryable

index.html

我们没有手动输入 URL 来测试我们的 API,而是使用此文件来创建链接以便于测试。

<!DOCTYPE html>
<head>
</head>
<body>
    <ul>
        <li><a target="_blank" href="/api/products">Default</a></li>
        <li><a target="_blank" href="/api/products?page=2">Page 2</a></li>
        <li><a target="_blank" href="/api/products?page=2&size=25">Page 2 and Size 25</a></li>
        <li><a target="_blank" href="/api/products?page=2&size=25&order=name">Page 2 and Size 25 and Order by name</a></li>
        <li><a target="_blank" href="/api/products?page=2&size=25&order=name&direction=desc">Page 2 and Size 25 and Order by name descending</a></li>
    </ul>
</body>
</html>

运行项目

dotnet run

打开 Web 浏览器并转到 http://localhost:5122
您将找到此测试页面。

测试

在没有任何参数的情况下进行测试

单击“默认”链接,它将打开 URLhttp://localhost:5122/api/products

API 将返回具有默认参数(page = 1 和 size = 10)的分页数据。

页面索引测试

单击“第 2 页”链接,它将打开 URLhttp://localhost:5122/api/products?page=2

API 将在第二页上返回分页数据,从产品 ID 11 开始

页面大小测试

单击“第 2 页和大小 25”链接,它将打开 URLhttp://localhost:5122/api/products?page=2&size=25

由于页面大小为 25,因此 API 将从产品 ID 26 开始,在第二个页面上返回分页数据。

订单测试

单击“第 2 页和大小 25 并按名称排序”链接,它将打开 URLhttp://localhost:5122/api/products?page=2&size=25&order=name

API 将在第二页上返回分页数据,但产品顺序基于产品名称。

降序测试

单击“第 2 页和大小 25 并按名称降序排序”链接,它将打开 URLhttp://localhost:5122/api/products?page=2&size=25&order=name&direction=desc

API 将在第二页上返回分页数据,但产品顺序基于产品名称的降序。

在本文中,你学习了如何利用实体框架轻松实现 .NET 应用程序的分页 API。分页方法将增强用户体验并加快 .NET API 的速度。

源代码获取:公众号回复消息【code:78289

相关代码下载地址
重要提示!:取消关注公众号后将无法再启用回复功能,不支持解封!
第一步:微信扫码关键公众号“架构师老卢”
第二步:在公众号聊天框发送code:78289,如:code:78289 获取下载地址
第三步:恭喜你,快去下载你想要的资源吧
阅读排行