Blazor Server 환경에서 RankingApp을 개발하여 사용자 인증 기반의 CRUD 기능을 학습합니다. 해당 프로젝트는 다음과 같은 목적을 가집니다:
RankingApp"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=RankingDB;Trusted_Connection=True;MultipleActiveResultSets=true"
}
RankingDBpublic class GameResult
{
public int Id { get; set; }
public int UserID { get; set; }
public string UserName { get; set; }
public int Score { get; set; }
public DateTime Date { get; set; }
}
public class ApplicationDbContext : IdentityDbContext
{
public DbSet<GameResult> GameResultList { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
}
DbSet<GameResult>를 통해 ORM 기반 DB 테이블 자동 생성builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddScoped<RankingService>();
PM> Add-Migration RankingService
PM> Update-Database
public class RankingService
{
private readonly ApplicationDbContext _context;
public RankingService(ApplicationDbContext context) { _context = context; }
public Task<List<GameResult>> GetGameResultAsync()
{
var results = _context.GameResultList.OrderByDescending(x => x.Score).ToList();
return Task.FromResult(results);
}
public Task<GameResult> AddGameResult(GameResult gameResult)
{
_context.GameResultList.Add(gameResult);
_context.SaveChanges();
return Task.FromResult(gameResult);
}
public Task<bool> UpdateGameResult(GameResult gameResult)
{
var result = _context.GameResultList.FirstOrDefault(x => x.Id == gameResult.Id);
if (result == null) return Task.FromResult(false);
result.UserName = gameResult.UserName;
result.Score = gameResult.Score;
_context.SaveChanges();
return Task.FromResult(true);
}
public Task<bool> DeleteGameResult(GameResult gameResult)
{
var result = _context.GameResultList.FirstOrDefault(x => x.Id == gameResult.Id);
if (result == null) return Task.FromResult(false);
_context.GameResultList.Remove(result);
_context.SaveChanges();
return Task.FromResult(true);
}
}
@page "/ranking"
@using RankingApp.Data.Models;
@using RankingApp.Data.Services;
@inject RankingService RankingService
<h3>Ranking</h3>
<AuthorizeView>
<Authorized>
@if (_gameResultList == null)
{
<p>Loading...</p>
}
else
{
<table class="table">
<thead>
<tr>
<th>UserName</th>
<th>Score</th>
<th>Date</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var result in _gameResultList)
{
<tr>
<td>@result.UserName</td>
<td>@result.Score</td>
<td>@result.Date</td>
<td><button class="btn btn-primary" @onclick="() => EditGameResult(result)">Edit</button></td>
<td><button class="btn btn-danger" @onclick="() => DeleteGameResult(result)">Delete</button></td>
</tr>
}
</tbody>
</table>
<button class="btn btn-success" @onclick="AddGameResult">Add</button>
@if (_showPopup)
{
<div class="modal" style="display:block">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Add/Update GameResult</h3>
<button type="button" class="close" @onclick="ClosePopup">X</button>
</div>
<div class="modal-body">
<label>UserName</label>
<input class="form-control" @bind-value="_gameResult.UserName" />
<label>Score</label>
<input class="form-control" @bind-value="_gameResult.Score" />
<button class="btn btn-primary" @onclick="SaveGameResult">Save</button>
</div>
</div>
</div>
</div>
}
}
</Authorized>
<NotAuthorized>
<p>You are not authorized to view this page.</p>
</NotAuthorized>
</AuthorizeView>
@code {
List<GameResult> _gameResultList;
GameResult _gameResult;
bool _showPopup = false;
protected override async Task OnInitializedAsync()
{
await ReadGameResults();
}
async Task ReadGameResults()
{
_gameResultList = await RankingService.GetGameResultAsync();
}
void AddGameResult()
{
_showPopup = true;
_gameResult = new GameResult { Id = 0 };
}
void EditGameResult(GameResult gameResult)
{
_showPopup = true;
_gameResult = gameResult;
}
async Task DeleteGameResult(GameResult gameResult)
{
await RankingService.DeleteGameResult(gameResult);
await ReadGameResults();
}
async Task SaveGameResult()
{
if (_gameResult.Id == 0)
{
_gameResult.Date = DateTime.Now;
await RankingService.AddGameResult(_gameResult);
}
else
{
await RankingService.UpdateGameResult(_gameResult);
}
_showPopup = false;
await ReadGameResults();
}
}
<NavLink class="nav-link" href="ranking">
<span class="oi oi-list-rich" aria-hidden="true"></span> Ranking
</NavLink>