GameStore.Api/Dtos.cs
| |
| using System.ComponentModel.DataAnnotations; |
| |
| namespace GameStore.Api.Dtos; |
| |
| |
| public record GameDto(int Id, |
| string Name, |
| string Genre, |
| decimal Price, |
| DateTime ReleaseDate, |
| string ImageUri); |
| public record CreateGameDto([Required][StringLength(50)] string Name, |
| [Required][StringLength(20)] string Genre, |
| [Range(1, 100)] decimal Price, |
| DateTime ReleaseDate, |
| [Url][StringLength(100)] string ImageUri); |
| |
| |
| |
| public record UpdateGameDto([Required][StringLength(50)] string Name, |
| [Required][StringLength(20)] string Genre, |
| [Range(1, 100)] decimal Price, |
| DateTime ReleaseDate, |
| [Url][StringLength(100)] string ImageUri); |
| |
| |
| |
| |
| |
GameStore.Api/GameStore.Api.csproj
| <Project Sdk="Microsoft.NET.Sdk.Web"> |
| |
| <PropertyGroup> |
| <TargetFramework>net8.0</TargetFramework> |
| <Nullable>enable</Nullable> |
| <ImplicitUsings>enable</ImplicitUsings> |
| <UserSecretsId>eff6d453-87a0-41c0-b286-ceb7a9aebd3c</UserSecretsId> |
| </PropertyGroup> |
| |
| <ItemGroup> |
| <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0"> |
| <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
| <PrivateAssets>all</PrivateAssets> |
| </PackageReference> |
| <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0" /> |
| <PackageReference Include="MinimalApis.Extensions" Version="0.11.0" /> |
| </ItemGroup> |
| |
| </Project> |
| |
| |
GameStore.Api/appsettings.json
| { |
| "Logging": { |
| "LogLevel": { |
| "Default": "Information", |
| "Microsoft.AspNetCore": "Warning" |
| } |
| }, |
| "AllowedHosts": "*", |
| "ConnectionStrings": { |
| "DefaultConnection": "Data Source=/Users/song/Code/dotnet_webapi_2/GameStore.Api/Dbs/Games.db" |
| } |
| } |
| |
GameStore.Api/appsettings.Development.json
| { |
| "Logging": { |
| "LogLevel": { |
| "Default": "Information", |
| "Microsoft.AspNetCore": "Warning" |
| } |
| } |
| } |
| |
GameStore.Api/Program.cs
| using GameStore.Api.Data; |
| using GameStore.Api.Endpoints; |
| using GameStore.Api.Repositoriesa; |
| using Microsoft.EntityFrameworkCore; |
| |
| var builder = WebApplication.CreateBuilder(args); |
| |
| |
| builder.Services.AddScoped<IGamesRepository, EntityFrameworkGamesRepository>(); |
| |
| builder.Services.AddRepositories(builder.Configuration); |
| |
| var app = builder.Build(); |
| |
| app.Services.InitalizeDb(); |
| |
| app.MapGet("/", () => "Hello World!"); |
| |
| app.MapGamesEndpoints(); |
| |
| app.Run(); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
GameStore.Api/Endpoints/GamesEndpoints.cs
| using System.Diagnostics.CodeAnalysis; |
| using System.Reflection.Metadata; |
| using GameStore.Api.Dtos; |
| using GameStore.Api.Entities; |
| using GameStore.Api.Repositoriesa; |
| |
| namespace GameStore.Api.Endpoints; |
| |
| public static class GamesEndpoints |
| { |
| |
| const string GetGameEndpointName = "GetGame"; |
| |
| |
| |
| |
| public static RouteGroupBuilder MapGamesEndpoints(this IEndpointRouteBuilder endpoints) |
| { |
| |
| var group = endpoints.MapGroup("/games").WithParameterValidation(); |
| |
| group.MapGet("/", (IGamesRepository repository) => repository.GetAll().Select(game => game.AsDto())); |
| |
| group.MapGet("/{id}", (IGamesRepository repository, int id) => |
| { |
| Game? game = repository.Get(id); |
| if (game is null) |
| { |
| return Results.NotFound(); |
| } |
| return Results.Ok(game.AsDto()); |
| }).WithName(GetGameEndpointName); |
| |
| group.MapPost("/", (IGamesRepository repository, CreateGameDto gameDto) => |
| { |
| |
| Game game = new() |
| { |
| Name = gameDto.Name, |
| Genre = gameDto.Genre, |
| Price = gameDto.Price, |
| ReleaseDate = gameDto.ReleaseDate, |
| ImageUri = gameDto.ImageUri |
| }; |
| repository.Create(game); |
| |
| return Results.CreatedAtRoute(GetGameEndpointName, new { id = game.Id }, game); |
| }); |
| |
| |
| |
| group.MapPut("/{id}", (IGamesRepository repository, int id, UpdateGameDto updatedGame) => |
| { |
| |
| Game? existingGame = repository.Get(id); |
| if (existingGame is null) |
| { |
| return Results.NotFound(); |
| } |
| existingGame.Name = updatedGame.Name; |
| existingGame.Genre = updatedGame.Genre; |
| existingGame.Price = updatedGame.Price; |
| existingGame.ReleaseDate = updatedGame.ReleaseDate; |
| existingGame.ImageUri = updatedGame.ImageUri; |
| |
| repository.Update(existingGame); |
| |
| return Results.NoContent(); |
| }); |
| |
| group.MapDelete("/{id}", (IGamesRepository repository, int id) => |
| { |
| Game? game = repository.Get(id); |
| if (game is not null) |
| { |
| repository.Delete(id); |
| } |
| return Results.NoContent(); |
| }); |
| |
| |
| return group; |
| |
| } |
| |
| } |
GameStore.Api/Repositories/EntityFrameworkGamesRepository.cs
| |
| using GameStore.Api.Data; |
| using GameStore.Api.Entities; |
| using Microsoft.EntityFrameworkCore; |
| |
| namespace GameStore.Api.Repositoriesa; |
| |
| |
| public class EntityFrameworkGamesRepository : IGamesRepository |
| { |
| private readonly GameStoreContext dbContext; |
| public EntityFrameworkGamesRepository(GameStoreContext dbContext) |
| { |
| this.dbContext = dbContext; |
| } |
| |
| public void Create(Game game) |
| { |
| dbContext.Games.Add(game); |
| dbContext.SaveChanges(); |
| } |
| |
| public void Delete(int id) |
| { |
| dbContext.Games.Where(game => game.Id == id).ExecuteDelete(); |
| } |
| |
| public Game? Get(int id) |
| { |
| |
| return dbContext.Games.Find(id); |
| } |
| |
| public IEnumerable<Game> GetAll() |
| { |
| |
| return dbContext.Games.AsNoTracking().ToList(); |
| } |
| |
| public void Update(Game updatedGame) |
| { |
| dbContext.Games.Update(updatedGame); |
| dbContext.SaveChanges(); |
| } |
| } |
GameStore.Api/Repositories/IGamesRepository.cs
| |
| using GameStore.Api.Entities; |
| |
| namespace GameStore.Api.Repositoriesa; |
| |
| public interface IGamesRepository |
| { |
| |
| IEnumerable<Game> GetAll(); |
| Game? Get(int id); |
| void Create(Game game); |
| void Update(Game updatedGame); |
| void Delete(int id); |
| } |
| |
| |
GameStore.Api/Repositories/InMemGamesRepository.cs
| |
| using GameStore.Api.Entities; |
| |
| namespace GameStore.Api.Repositoriesa; |
| |
| |
| public class InMemGamesRepository : IGamesRepository |
| { |
| |
| private readonly List<Game> games = new() |
| { |
| new Game(){ |
| Id = 1, |
| Name="Street Fighter II", |
| Genre ="Fighting", |
| Price = 19.99M, |
| ReleaseDate = new DateTime(1991,2,1), |
| ImageUri = "https://palcehold.co/100" |
| }, |
| new Game(){ |
| Id = 2, |
| Name="FIFA 23", |
| Genre ="Sports", |
| Price = 29.99M, |
| ReleaseDate = new DateTime(2022,2,1), |
| ImageUri = "https://palcehold.co/100" |
| }, |
| |
| }; |
| |
| public IEnumerable<Game> GetAll() |
| { |
| return games; |
| } |
| public Game? Get(int id) |
| { |
| return games.Find(game => game.Id == id); |
| } |
| public void Create(Game game) |
| { |
| game.Id = games.Max(game => game.Id) + 1; |
| games.Add(game); |
| } |
| public void Update(Game updatedGame) |
| { |
| var index = games.FindIndex(game => game.Id == updatedGame.Id); |
| games[index] = updatedGame; |
| } |
| public void Delete(int id) |
| { |
| var index = games.FindIndex(game => game.Id == id); |
| games.RemoveAt(index); |
| } |
| |
| |
| } |
GameStore.Api/Data/GameStoreContext.cs
| using System.Reflection; |
| using GameStore.Api.Entities; |
| using Microsoft.EntityFrameworkCore; |
| |
| namespace GameStore.Api.Data; |
| public class GameStoreContext : DbContext |
| { |
| public GameStoreContext(DbContextOptions<GameStoreContext> options) : base(options) |
| { |
| } |
| public DbSet<Game> Games => Set<Game>(); |
| |
| protected override void OnModelCreating(ModelBuilder modelBuilder) |
| { |
| |
| modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); |
| |
| } |
| } |
GameStore.Api/Data/DataExtensions.cs
| |
| using Microsoft.EntityFrameworkCore; |
| |
| namespace GameStore.Api.Data; |
| |
| public static class DataExtensions |
| { |
| |
| |
| public static void InitalizeDb(this IServiceProvider provider) |
| { |
| using var scope = provider.CreateScope(); |
| var dbContext = scope.ServiceProvider.GetRequiredService<GameStoreContext>(); |
| dbContext.Database.Migrate(); |
| } |
| |
| public static IServiceCollection AddRepositories(this IServiceCollection services, IConfiguration configuration) |
| { |
| |
| services.AddSqlite<GameStoreContext>(configuration.GetConnectionString("DefaultConnection")); |
| return services; |
| } |
| } |
| |
GameStore.Api/Data/Configurations/GameConfigurations.cs
| |
| using GameStore.Api.Entities; |
| using Microsoft.EntityFrameworkCore; |
| using Microsoft.EntityFrameworkCore.Metadata.Builders; |
| |
| namespace GameStore.Api.Data.Configurationsa; |
| |
| public class GameConfiguration : IEntityTypeConfiguration<Game> |
| { |
| |
| public void Configure(EntityTypeBuilder<Game> builder) |
| { |
| builder.Property(game => game.Price).HasPrecision(5, 2); |
| } |
| } |
| |
GameStore.Api/Entities/Game.cs
| using System.ComponentModel.DataAnnotations; |
| |
| namespace GameStore.Api.Entities; |
| |
| public class Game |
| { |
| public int Id { get; set; } |
| [Required] |
| [StringLength(50)] |
| public required string Name { get; set; } |
| [Required] |
| [StringLength(20)] |
| public required string Genre { get; set; } |
| [Range(1,100)] |
| public decimal Price { get; set; } |
| public DateTime ReleaseDate { get; set; } |
| public required string ImageUri { get; set; } |
| |
| } |
GameStore.Api/Entities/EntityExtensions.cs
| using GameStore.Api.Dtos; |
| |
| namespace GameStore.Api.Entities; |
| |
| public static class EntityExtensions |
| { |
| public static GameDto AsDto(this Game game) |
| { |
| return new GameDto(game.Id, |
| game.Name, |
| game.Genre, |
| game.Price + 10, |
| game.ReleaseDate, |
| game.ImageUri); |
| |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2022-01-07 U盘被切割成两个硬盘,如何恢复成一个?