C#

C# MSSQL 데이터 연동 완전정복: 동기/비동기, CRUD, 그리고 실무 패턴

로기221 2025. 5. 13. 11:08
728x90
반응형

 

 

 

C#에서 MSSQL 데이터베이스와 연동하는 기본적인 방법을 아래와 같이 정리할 수 있습니다. 실무에서 가장 많이 사용하는 SqlConnection SqlCommand를 활용한 데이터 조회(SELECT) 및 삽입(INSERT) 예제를 포함합니다.

1. MSSQL 연동 준비

  • 네임스페이스 추가
     
    using System.Data.SqlClient;
     
  • Connection String 설정
    • SQL 인증 예시:
       
      string connStr = "Data Source=192.168.0.1,1433;Initial Catalog=DataBase;User ID=user1;Password=1234;";
    • Windows 인증 예시:
       
      string connStr = "Data Source=(local);Initial Catalog=DataBase;Integrated Security=SSPI;";
       
    • [포트는 쉼표로 구분하며], 각 항목은 세미콜론(;)으로 구분합니다.

2. 데이터 조회(SELECT) 예제

using System;
using System.Data;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        string connStr = "Data Source=192.168.0.1,1433;Initial Catalog=DataBase;User ID=user1;Password=1234;";
        using (SqlConnection conn = new SqlConnection(connStr))
        {
            conn.Open();
            string sql = "SELECT id, name FROM UserInfo";
            using (SqlCommand cmd = new SqlCommand(sql, conn))
            {
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Console.WriteLine($"ID: {reader["id"]}, Name: {reader["name"]}");
                    }
                }
            }
        }
    }
}
  • SqlConnection으로 DB 연결, SqlCommand로 쿼리 실행, SqlDataReader로 결과를 읽어옵니다.

3. 데이터 삽입(INSERT) 예제

using System;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        string connStr = "Data Source=192.168.0.1,1433;Initial Catalog=DataBase;User ID=user1;Password=1234;";
        using (SqlConnection conn = new SqlConnection(connStr))
        {
            conn.Open();
            string sql = "INSERT INTO UserInfo (id, name) VALUES (@id, @name)";
            using (SqlCommand cmd = new SqlCommand(sql, conn))
            {
                cmd.Parameters.AddWithValue("@id", 1);
                cmd.Parameters.AddWithValue("@name", "홍길동");
                int rows = cmd.ExecuteNonQuery();
                Console.WriteLine($"{rows} row(s) inserted.");
            }
        }
    }
}
  • ExecuteNonQuery()는 삽입, 수정, 삭제 쿼리에서 영향받은 행의 수를 반환합니다.

4. 참고 및 실무 팁

  • Connection String의 각 항목(서버, 포트, DB명, 사용자, 비밀번호 등)은 환경에 맞게 수정하세요.
  • using 구문을 사용하면 연결이 자동으로 닫혀 자원 관리가 편리합니다.
  • 실무에서는 예외 처리와 트랜잭션 관리도 중요합니다.
  • SqlDataAdapter DataSet을 활용하면 DataGridView 등 UI에 데이터 바인딩도 쉽게 할 수 있습니다.

 

스크립트(자바스크립트/AJAX)로 비동기 데이터 연동

  • ASP.NET MVC/Web API에서 Controller를 만들고,
    프론트엔드(JavaScript, jQuery, Fetch 등)에서 AJAX로 비동기 호출을 하여 데이터를 주고받는 방식입니다.
  • 이 방식은 UI를 새로고침하지 않고 서버에서 데이터를 받아와 화면에 바로 반영할 수 있어
    SPA(Single Page Application)나 대시보드, 실시간 데이터 등에 많이 사용됩니다.

예시 흐름

  1. Controller (C#)
     
  2. [HttpGet]
    public async Task<IActionResult> GetUser(int id)
    {
        var user = await _userService.GetUserAsync(id);
        return Json(user);
    }
  3. JavaScript (AJAX)
     
  4. fetch('/Controller/GetUser?id=1')
      .then(res => res.json())
      .then(data => {
        // data를 화면에 반영
      });

  • 비동기 처리는 C#의 async/await와 JS의 Promise/then, async/await로 자연스럽게 연동됩니다.

2. Controller, DataController, Data.cs 구조로 레이어 분리

  • Controller: 사용자 요청을 받고, View에 데이터를 전달하는 역할 (MVC의 C)
  • DataController: 실무에서는 주로 API 역할(RESTful API, 데이터만 반환)
  • Data.cs: 데이터 액세스 레이어(Repository, Service 등에서 DB와 직접 통신)

예시 구조

- Controllers/
    - UserController.cs      // View와 상호작용
    - UserApiController.cs   // 데이터만 반환 (API)
- Data/
    - UserRepository.cs      // DB 쿼리, CRUD 메서드
    - User.cs                // Entity(모델)

코드 예시

User.cs (Entity)

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

 

UserRepository.cs (Data Layer)

public class UserRepository
{
    private readonly string _connStr = "...";

    public async Task<User> GetUserAsync(int id)
    {
        using (var conn = new SqlConnection(_connStr))
        {
            await conn.OpenAsync();
            var cmd = new SqlCommand("SELECT Id, Name FROM Users WHERE Id=@id", conn);
            cmd.Parameters.AddWithValue("@id", id);
            using (var reader = await cmd.ExecuteReaderAsync())
            {
                if (await reader.ReadAsync())
                {
                    return new User
                    {
                        Id = reader.GetInt32(0),
                        Name = reader.GetString(1)
                    };
                }
            }
        }
        return null;
    }
}

 

UserApiController.cs (API Controller)

[ApiController]
[Route("api/[controller]")]
public class UserApiController : ControllerBase
{
    private readonly UserRepository _repo = new UserRepository();

    [HttpGet("{id}")]
    public async Task<ActionResult<User>> Get(int id)
    {
        var user = await _repo.GetUserAsync(id);
        if (user == null) return NotFound();
        return Ok(user);
    }
}

 

프론트엔드에서 비동기 호출

fetch('/api/UserApi/1')
  .then(res => res.json())
  .then(user => {
    // user 데이터 사용
  });

3. 실무에서의 추천

  • 비동기(Async/Await)와 레이어 분리를 함께 쓰면, 확장성과 유지보수성이 높아집니다.
  • Controller와 Data Layer(Repository, Service 등)를 분리하면 테스트, 재사용, 코드 관리가 쉬워집니다.
  • 프론트엔드에서 AJAX/Fetch로 비동기 호출하면 사용자 경험(UX)이 좋아집니다.

결론

  • 스크립트로 비동기 연동(AJAX, Fetch)
  • Controller, DataController, Data.cs 등 레이어 분리,
    둘 다 실무에서 널리 쓰이는 방식이며, 원하는 구조로 얼마든지 구현 가능합니다!
728x90
반응형