怪物奇妙物语

宇宙无敌超级美少男的怪物奇妙物语

首页 新随笔 联系 管理
  822 随笔 :: 0 文章 :: 2 评论 :: 16万 阅读

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, InMemGamesRepository>();
// builder.Services.AddSingleton<IGamesRepository, InMemGamesRepository>();
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 RouteHandlerBuilder MapGet(this IEndpointRouteBuilder endpoints, [StringSyntax("Route")] string pattern, Delegate handler);
// public static RouteGroupBuilder MapGroup(this IEndpointRouteBuilder endpoints, [StringSyntax("Route")] string prefix);
// 扩展 IEndpointRouteBuilder 接口
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
{
// 扩展 IServiceProvider接口的方法
public static void InitalizeDb(this IServiceProvider provider)
{
using var scope = provider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<GameStoreContext>();
dbContext.Database.Migrate();
}
// 扩展IServiceCollection接口的方法
public static IServiceCollection AddRepositories(this IServiceCollection services, IConfiguration configuration)
{
// config sqlite
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);
}
}
posted on   超级无敌美少男战士  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2022-01-07 U盘被切割成两个硬盘,如何恢复成一个?
点击右上角即可分享
微信分享提示