[blazor] Ercore를 이용한 CRUD 구현 및 CRUD,List페이지 구현

코찔찔이·2023년 9월 18일
0

blazor강의 따라하기

목록 보기
22/23
  1. Video페이지 ER.Core를 이용한 CRUD구현 및 view페이지 생성.
  2. Edit, Details, Delete 페이지는 /Video/각 페이지/{id}로 라우팅을 설정하고
    이동시 id를 넘겨주고 각페이지에서는 id를 기준으로 row를 검색해서 작업 진행.
  3. 소스코드 github경로

1. index(List)페이지

  1. Video테이블의 데이터를 List로 보여줌.
  1. 화면

  2. 코드(Index.razor)

@page "/Videos"
@page "/Videos/Index"

@inject IVideoRepositoryAsync repository

<h3>상세페이지</h3>

<div>
    <a href="/Videos/Create" class="btn btn-primary">Create</a>
</div>

@if (videos == null)
{
    <p>Loading...</p>
}
else if (videos.Count == 0)
{
    <p>Nodata...</p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Title</th>
                <th>URL</th>
                <th>&nbsp;</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var video in videos)
            {
                <tr>
                    <td>@video.Id</td>
                    <td>@video.Title</td>
                    <td><a href="@video.Url">@video.Url</a> </td>
                    <td><a href="/Videos/Details/@video.Id">Details</a></td>
                    <td><a href="/Videos/Edit/@video.Id">Edit</a></td>
                    <td><a href="/Videos/Delete/@video.Id">Delete</a></td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    List<Video> videos = new List<Video>();

    protected override async Task OnInitializedAsync()
    {
        videos = await repository.GetVideosAsync();
    }

}

2. Create 페이지

  1. 아래 이미지처럼 Created,Modified가 null 허용 및 default값으로 GetDate()를 넣게 되어 있는데 ER core의 문제인지는 모르겠으나 두개의 컬럼에 date값을 넣어 주지 않으면 에러가 발생함.
    VideoDbContext.cs에 아래 코드를 추가해 주면 create시 아래와 같이 두개 컬럼에 default값을 지정해서 넣어줄 수 있음.
    protected override void OnModelCreating(ModelBuilder modelBuilder) { //[!] vidoes 테이블의 created,modified 열을 자동으로 GetDate() 제약 조건을 부여 함. modelBuilder.Entity<Video>().Property(x => x.Created).HasDefaultValueSql("GetDate()"); modelBuilder.Entity<Video>().Property(x => x.Modified).HasDefaultValueSql("GetDate()"); }
  1. 데이터 베이스 스키마

  2. 날짜 컬럼에 값을 넣어 주지 않으면 아래와 같은 에러 발생.

  1. 입력전

  2. create

  3. create후

  4. url 선택시 url경로가 https:// 혹은 http://를 붙여주지 않으면 아래와 같이
    localhost즉 blazor 페이지에서 라우팅 하게됨. 전체 경로를 넣어줘야 함.
    해당 url은 edit 페이지에서 수정 예정.

5.코드( Create.razor)

@page "/Videos/Create"

@inject IVideoRepositoryAsync repository
@inject NavigationManager navigationManager

<h3>Create</h3>

<from>
    <div class="row">
        <div class="col-md-8">
            <div class="form-group">
                <label for="Title" class="control-label">Title</label>
                <input type="text" @bind="@video.Title" class="form-control" />
            </div>
            <div class="form-group">
                <label for="Url" class="control-label">Url</label>
                <input type="text" @bind="@video.Url" class="form-control" />
            </div>
            <div class="form-group">
                <label for="Name" class="control-label">Name</label>
                <input type="text" @bind="@video.Name" class="form-control" />
            </div>
            <div class="form-group">
                <label for="Company" class="control-label">Company</label>
                <input type="text" @bind="@video.Company" class="form-control" />
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-4">
            <input type="button" id="btnSave" value="Save" @onclick="CreateEvent" />
            <input type="button" id="OnCancelEvent" value="Cancel" @onclick="OnCancelEvent" />
        </div>
    </div>
</from>

@code {
    Video video = new Video();

    protected async Task CreateEvent()
    {
        await repository.AddVideoAsync(video);
        navigationManager.NavigateTo("/Videos");
    }

    protected void OnCancelEvent()
    {
        navigationManager.NavigateTo("/Videos/Index");
    }
}
  1. create시 default값을 넣는 코드(VideoDbContext.cs)
//Install-Package Microsoft.EntityFrameworkCore.SqlServer
//Install-Package System.Configuration.ConfigurationManager

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text;

namespace VideoAppCoreModels
{
    public class VideoDbContext : DbContext
    {
        public VideoDbContext(DbContextOptions<VideoDbContext> options)
            : base(options)
        {
            //공식과 같은코드
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            // 닷넷 프레임워크 기반에서 호출되는 코드 영역:
            // App.Config 또는 Web.Config의 연결 문자열 사용
            if(!optionsBuilder.IsConfigured)
            {
                string connectionString = ConfigurationManager.ConnectionStrings[
                    "DefaultConnection"].ConnectionString;
                optionsBuilder.UseSqlServer(connectionString);
            }
        }

        /// <summary>
        /// 비디오앱
        /// </summary>
        public DbSet<Video> Videos { get; set; }


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //[!] vidoes 테이블의 created,modified 열을 자동으로 GetDate() 제약 조건을 부여 함.
            modelBuilder.Entity<Video>().Property(x => x.Created).HasDefaultValueSql("GetDate()");
            modelBuilder.Entity<Video>().Property(x => x.Modified).HasDefaultValueSql("GetDate()");
        }
    }
}

3. Edit페이지

  1. url에서 Id값을 받아 해당 row를 Db에서 검색후 수정 기능 구현.
  2. 위에서 잘못 기재된 url 수정 구현.
  3. Edit 버튼: 수정 커밋, Delete 버튼 : delete 페이지로 이동, Cancel: index페이지(List 페이지)로 이동.
  1. 수정전

  2. 수정페이지

  3. 데이터 수정 후 edit버튼을 누르면 js기능인 confirm을 띄어 수정 확인을 받고 확인 버튼을 누르면 데이터 수정후 list페이지로 이동.

  4. 수정 후

  5. code(Edit.razor)

@page "/Videos/Edit/{id}"


@inject IVideoRepositoryAsync repository
@inject IJSRuntime js
@inject NavigationManager nav

<h3>Edit</h3>


<from>
    <div class="row">
        <div class="col-md-8">
            <div class="form-group">
                <label>ID</label><br />
                @video.Id
                <hr />
            </div>
            <div class="form-group">
                <label>TITLE</label><br />
                <input type="text" @bind="@video.Title" />
                <hr />
            </div>
            <div class="form-group">
                <label>URL</label><br />
                <input type="text" @bind="@video.Url" />
                <hr />
            </div>
            <div class="form-group">
                <label>NAME</label><br />
                <input type="text" @bind="@video.Name" />
                <hr />
            </div>
            <div class="form-group">
                <label>CREATED</label><br />
                @video.Created
                <hr />
            </div>
            <div>
                <input type="button" id="OnEditEvent" @onclick="OnEditEvent" value="Edit" />
                <input type="button" id="OnGotoDelete" @onclick="OnGotoDelete" value="Delete" />
                <input type="button" id="OnCancelEvent" @onclick="OnCancelEvent" value="Cancel" />
            </div>
        </div>
    </div>
</from>

@code {
    Video video = new Video();
    int id = 0;

    [Parameter]
    public string Id { get; set; }

    protected override async Task OnInitializedAsync()
    {
        id = int.Parse(Id);

        video = await repository.GetVideoByIdAsync(id);
    }

    protected async Task OnEditEvent()
    {
        bool is_check = await js.InvokeAsync<bool>("confirm", "정말 수정 하시겠습니까??");


        if (is_check)
        {
            await repository.UpdateVideoAsync(video);
            nav.NavigateTo("/Videos/Index");

        }
        else
        {
            await js.InvokeAsync<object>("alert", "취소 되었습니다.");
        }
    }

    protected void OnGotoDelete()
    {
        nav.NavigateTo($"/Videos/Delete/{Id}");
    }

    protected void OnCancelEvent()
    {
        nav.NavigateTo("/Videos/Index");
    }
}

4. Delete페이지

  1. url에서 Id값을 받아 해당 row를 Db에서 검색후 해당 row 삭제 기능.
  2. 아이디가 7인 row 삭제 예정.
  3. Delete 버튼: row삭제 커밋, Edit 버튼 : Edit 페이지로 이동, Cancel: index페이지(List 페이지)로 이동.
  1. 삭제전

  2. 삭제페이지

  1. 데이터 수정 후 delete버튼을 누르면 js기능인 confirm을 띄어 수정 확인을 받고 확인 버튼을 누르면 데이터 삭제후 list페이지로 이동.
  1. 수정 후
  1. code(Delete.razor)
@page "/Videos/Delete/{id}"

@inject IVideoRepositoryAsync repository
@inject IJSRuntime js
@inject NavigationManager nav

<h3>Delete</h3>


<from>
    <div class="row">
        <div class="col-md-8">
            <div class="form-group">
                <label>ID</label><br />
                @video.Id
                <hr />
            </div>
            <div class="form-group">
                <label>TITLE</label><br />
                @video.Title
                <hr />
            </div>
            <div class="form-group">
                <label>URL</label><br />
                @video.Url
                <hr />
            </div>
            <div class="form-group">
                <label>NAME</label><br />
                @video.Name
                <hr />
            </div>
            <div class="form-group">
                <label>CREATED</label><br />
                @video.Created
                <hr />
            </div>
            <div>
                <input type="button" id="OnDeleteEvent" @onclick="OnDeleteEvent" value="Delete" />
                <input type="button" id="OnDeleteEvent" @onclick="OnGotoEdit" value="Edit" />
                <input type="button" id="OnCancelEvent" @onclick="OnCancelEvent" value="Cancel" />
            </div>
        </div>
    </div>
</from>

@code {
    Video video = new Video();
    int id = 0;

    [Parameter]
    public string Id { get; set; }

    protected override async Task OnInitializedAsync()
    {
        id = int.Parse(Id);

        video = await repository.GetVideoByIdAsync(id);
    }

    protected async Task OnDeleteEvent()
    {
        bool is_check = await js.InvokeAsync<bool>("confirm", "정말 삭제 하시겠습니까??");


        if (is_check)
        {
            await repository.RemoveVideoAsync(id);
            nav.NavigateTo("/Videos/Index");

        }
        else
        {
            await js.InvokeAsync<object>("alert", "취소 되었습니다.");
        }
    }

    protected void OnGotoEdit()
    {
        nav.NavigateTo($"/Videos/Edit/{Id}");
    }

    protected void OnCancelEvent()
    {
        nav.NavigateTo("/Videos/Index");
    }

}

5. Details 페이지

  1. url에서 Id값을 받아 해당 row를 Db에서 검색후 해당 row 상세 내역 조회.
  2. Delete 버튼: delete페이지로 이동, Edit 버튼 : Edit 페이지로 이동, Cancel: index페이지(List 페이지)로 이동.
  1. Details페이지

  2. code(Details.razor)

@page "/Videos/Details/{id}"

@inject IVideoRepositoryAsync repository
@inject IJSRuntime js

<h3>Details</h3>


<from>
    <div class="row">
        <div class="col-md-8">
            <div class="form-group">
                <label>ID</label><br />
                @video.Id
                <hr />
            </div>
            <div class="form-group">
                <label>TITLE</label><br />
                @video.Title
                <hr />
            </div>
            <div class="form-group">
                <label>URL</label><br />
                @video.Url
                <hr />
            </div>
            <div class="form-group">
                <label>NAME</label><br />
                @video.Name
                <hr />
            </div>
            <div class="form-group">
                <label>CREATED</label><br />
                @video.Created
                <hr />
            </div>
            <div>
                <a href="/Videos/Edit/@video.Id">Edit</a>
                <a href="/Videos/Delete/@video.Id">Delete</a>
                <a href="/Videos/">List</a>
            </div>
        </div>
    </div>
</from>

@code {
    Video video = new Video();
    int id = 0;

    [Parameter]
    public string Id { get; set; }

    protected override async Task OnInitializedAsync()
    {
        id = int.Parse(Id);

        video = await repository.GetVideoByIdAsync(id);
    }

    // protected override async Task OnAfterRenderAsync(bool firstRender)
    // {
    //     await InvokeAsync(StateHasChanged);
    // }

}

0개의 댓글