[Blazor] Blazor + Mysql > C#/.Net/Blazor/IIS

본문 바로가기
사이트 내 전체검색

C#/.Net/Blazor/IIS

[Blazor] Blazor + Mysql

페이지 정보

작성자 sbLAB 댓글 0건 조회 7,233회 작성일 21-03-20 18:31

본문

1. BlazorServer 웹프로젝트 생성 
 

[DBLibrary]

2. mysql 연동에 사용할 DBLibrary  프로젝트(Class Library) 생성 

    - Dapper(2.0.78)

    - Mysql.Data(8.0.23) 설치(nuget)


3. 디비 접근 구조 인터페이스 IDbAccess 생성


namespace DBLibrary
{
    public interface IDbAccess
    {
        Task<List<T>> LoadData<TU>(string sqlU parametersstring connectionString);
        Task SaveData<T>(string sqlT parametersstring connectionString);
    }
}
4. DB 접근 구조(IDbAccess)에 대한 인터페이스 구현(MysqlAccess)
namespace DBLibrary
{
    public class MysqlAccess : IDbAccess
    {
        public async Task<List<T>> LoadData<TU>(string sqlU parametersstring connectionString)        
        {
            using (IDbConnection connection = new MySqlConnection(connectionString))            {
                var rows = await connection.QueryAsync<T>(sqlparameters);
                return rows.ToList();
            }
        }
 
        public Task SaveData<T>(string sqlT parametersstring connectionString)        {
            using (IDbConnection connection = new MySqlConnection(connectionString))
            {
                return connection.ExecuteAsync(sqlparameters);
            }
        }
    }
5. BlazorServer 웹프로젝트 Dependencies에 DBLibrary 연결등록
6. [Shared] -> appsettings.json 에 mysql DB정보 세팅
{
  "Logging": {
    "LogLevel": {
      "Default""Information",
      "Microsoft""Warning",
      "Microsoft.Hosting.Lifetime""Information"
    }
  },
  "AllowedHosts""*",
  "ConnectionStrings": {
    "default""Server=localhost;Port=3306;database=blazor;user id=blazor;password=1111;charset=utf8"
   //"default": "Server=localhost;Port=3306;database=blazor;user id=blazor;password=1111;OldGuids=True;charset=utf8"
  }
}

7. BlazorServer 프로젝트  Startup.cs 에서 ConfigureServices 부품박스(컨테이너)에 부품사용등록
public void ConfigureServices(IServiceCollection services)
   {
       services.AddRazorPages();
       services.AddServerSideBlazor();
       services.AddSingleton<IDbAccessMysqlAccess>();
   }

8. Blazor People.razor 페이지에서 사용
[데이타 모델 구조]
namespace BlazorServer.Models
{
    public class PersonModel
    {
        public string Name { getset; }
        public string Point { getset; }
    }
}
[ razor 페이지에 부품 연결(inject) 사용]
@page "/people"
 
@using DBLibrary
@using BlazorServer.Models
@using Microsoft.Extensions.Configuration
@inject IDbAccess _data
@inject IConfiguration _config
 
<h3>People</h3>
 
<button class="btn btn-primary" @onclick="InsertData">Insert</button>
<button class="btn btn-warning" @onclick="UpdateData">Update</button>
<button class="btn btn-danger" @onclick="DeleteData">Delete</button>
 
@if (people == null)
{
    <p><em>Loading...</em></p>
}
else
{
    @foreach (var p in people)
    {
        <p>
            @p.Name @p.Point
        </p>
    }
}

@code {
    List<PersonModel> people;
 
    private async Task InsertData()
    {
        string sql = "insert into people (Name, Point) values (@Name, @Point);";
        await _data.SaveData(sqlnew { Name = "Billy", Point = "300" }, _config.GetConnectionString("default"));
        await OnInitializedAsync();
    }
 
    private async Task UpdateData()
    {
        string sql = "update people set Name = @Name where Point = @Point";
        await _data.SaveData(sqlnew { Name = "Timothy", Point = "100" }, _config.GetConnectionString("default"));
        await OnInitializedAsync();
    }
 
    private async Task DeleteData()
    {
        string sql = "delete from people where Point = @Point";
        await _data.SaveData(sqlnew { Point = "70" }, _config.GetConnectionString("default"));
        await OnInitializedAsync();
    }
 
    protected override async Task OnInitializedAsync()
    {
        string sql = "select * from people";
        people = await _data.LoadData<PersonModeldynamic>(sqlnew { }, _config.GetConnectionString("default"));
    }
 
}


[People 페이지를 partial behind code로 만든다면 아래와 같다. 분리가 프로그램 같아서 좋다.]

988e472cd6a387be069319ba90fd836d_1616238606_5162.JPG

[People.razor]

@page "/people"
<h3>People</h3>
 
<button class="btn btn-primary" @onclick="InsertData">Insert</button>
<button class="btn btn-warning" @onclick="UpdateData">Update</button>
<button class="btn btn-danger" @onclick="DeleteData">Delete</button>
 
@if (people == null)
{
    <p><em>Loading...</em></p>
}
else
{
    @foreach (var p in people)
    {
        <p>
            @p.Name @p.Point
        </p>
    }
}
 

[People.razor.cs]

using BlazorServer.Models;
using DBLibrary;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Threading.Tasks;
 
 
namespace BlazorServer.Pages
{
    public partial class People
    {
        [Inject]
        public IDbAccess _data getset; }
        [Inject]
        public IConfiguration _config getset; }
 
        List<PersonModel> people;
 
        private async Task InsertData()
        {
            string sql = "insert into people (Name, Point) values (@Name, @Point);";
            await _data.SaveData(sqlnew { Name = "Billy", Point = "300" }, _config.GetConnectionString("default"));
            await OnInitializedAsync();
        }
 
        private async Task UpdateData()
        {
            string sql = "update people set Name = @Name where Point = @Point";
            await _data.SaveData(sqlnew { Name = "Timothy", Point = "100" }, _config.GetConnectionString("default"));
            await OnInitializedAsync();
        }
 
        private async Task DeleteData()
        {
            string sql = "delete from people where Point = @Point";
            await _data.SaveData(sqlnew { Point = "70" }, _config.GetConnectionString("default"));
            await OnInitializedAsync();
        }
 
        protected override async Task OnInitializedAsync()
        {
            string sql = "select * from people";
            people = await _data.LoadData<PersonModeldynamic>(sqlnew { }, _config.GetConnectionString("default"));
        }
    }
}

//위 소스 개선할 점 -> MysqlAccess 변수명을 DbAccess 로 변경필요
MysqlAccess.cs ->DbAccess.cs 로 파일명 변경
[DbAccess.cs]
public class DbAccess : IDbAccess

 

[Startup.cs]

services.AddSingleton<IDbAccessDbAccess>(); 


[이유]

DI 패턴 목적이 DB종류가 바뀔때 소스 수정을 최소화 하는것인데, MysqlAccess 로 변수명을 결정짓고 있다.

처음부터 DbAccess 로 하고, 만약 DB가 변경된다면 오로지 DbAccess.cs 에서 각 DB연동 로직만 변경하면 된다.

namespace DBLibrary
{
    public class DbAccess : IDbAccess
    {
        public async Task<List<T>> LoadData<TU>(string sqlU parametersstring connectionString)        
        {
            using (IDbConnection connection = new MySqlConnection(connectionString))            {
                var rows = await connection.QueryAsync<T>(sqlparameters);
                return rows.ToList();
            }
        }

        public Task SaveData<T>(string sqlT parametersstring connectionString)        {
            using (IDbConnection connection = new MySqlConnection(connectionString))
            {
                return connection.ExecuteAsync(sqlparameters);
            }
        }
    }
}

[DI] ?
DI부품박스제어통(컨테이너)한테 부품(클래스)사용등록한다고 알려준다(외부에서 설정값으로 설정)
razor 페이지나 다른 로직에서 사용할때, 개발자가 소스에 부품 클래스 인스턴스를 생성하는
컴파일단계의 로직을 직접만들지 않고,
그 클래스는 [Inject] 하겠다는 표시를 해주면, 실행단계에서 그 클래스의 인스턴스를 알아서 연결(넣어)해준다.
그리고, 그 인스턴스를 이하 로직에서 사용하게된다.

내부에서 _repo  인스턴스 생성하는 경우
[Route("api/commands")]
    [ApiController]
    public class CommandsController : ControllerBase
    {  
        private readonly MockCommanderRepo _repo = new MockCommanderRepo();
        
        //GET api/commands
        [HttpGet]
        public ActionResult <IEnumerable<Command>>GetAllCommands()
        {
            var commandItems = _repo.GetAllCommands();
            return OK(commandItems);
        }

        //GET api/commands/2
        [HttpGet("{id}")]
        public ActionResult <IEnumerable<Command>>GetCommandById(id);
        {
            var commandItem = _repo.GetCommandById(id);
            return OK(commandItem);
        }        
    }


외부에서 부품사용 등록 후 DI로 넣는 경우(Constructor 로 들어옴)
    services.AddScoped<ICommanderRepoMockCommanderRepo>(); 
--------------------------------------------------------

    [Route("api/commands")]
    [ApiController]
    public class CommandsController : ControllerBase
    {  
        //private readonly MockCommanderRepo _repo = new MockCommanderRepo();
        private readonly ICommanderRepo _repo;

        public CommandsController(ICommanderRepo repo){
          _repo = repo;  
        }
        
        //GET api/commands
        [HttpGet]
        public ActionResult <IEnumerable<Command>>GetAllCommands()
        {
            var commandItems = _repo.GetAllCommands();
            return OK(commandItems);
        }

        //GET api/commands/2
        [HttpGet("{id}")]
        public ActionResult <IEnumerable<Command>>GetCommandById(id);
        {
            var commandItem = _repo.GetCommandById(id);
            return OK(commandItem);
        }        
    }

--------------------------------------------------------------

[IDbAccess 인터페이스, DbAccess 클래스 모두 적시] - OK
services.AddSingleton<IDbAccessDbAccess>();   
 [Inject]
 public IDbAccess _data { getset; }
_data.*** 사용
[이 게시물은 sbLAB님에 의해 2022-12-22 09:42:42 Web/PHP/API에서 이동 됨]

첨부파일

댓글목록

등록된 댓글이 없습니다.

회원로그인

접속자집계

오늘
109
어제
190
최대
1,279
전체
232,730

그누보드5
Copyright © sebom.com All rights reserved.