C#을 사용하여 데이터베이스(Database)와 상호작용하는 것은 어플리케이션에서 데이터를 저장하고 관리할 수 있는 강력한 방법을 제공합니다.
C#에서 데이터베이스를 사용하는 주요 방법은 ADO.NET, 엔티티 프레임워크(Entity Framework), 그리고 Dapper와 같은 마이크로 ORM 라이브러리를 포함합니다.
이러한 각각의 기술들은 서로 다른 사용 케이스와 선호도에 따라 선택될 수 있습니다.

C# 에서 Database 사용하기 소개
기본 개념
- 데이터베이스 연결:
- 데이터베이스 작업을 시작하기 전에 C# 어플리케이션에서는 데이터베이스 서버와 연결을 설정해야 합니다.
- 이 연결은 일반적으로 연결 문자열을 사용하여 구성되며, 이 문자열에는 서버의 위치, 데이터베이스 이름, 접근 권한을 위한 사용자 이름과 비밀번호가 포함됩니다.
- 명령 실행 (with SQL):
- 데이터베이스에 연결한 후, SQL 문을 실행하여 데이터를 조회, 추가, 수정, 삭제할 수 있습니다.
- 이 명령들은 데이터베이스 서버에 의해 처리되고 결과가 반환됩니다.
- 데이터 처리:
- 데이터를 데이터베이스에서 가져오거나 데이터베이스에 보낸 후, 이 데이터를 C# 코드 내에서 객체로 매핑하고 처리하는 과정을 포함합니다.
MySQL 사용 및 준비
본 포스팅에서는 Database로 MySQL을 사용할 예정입니다.
C#에서 MySQL을 사용하기 위해 NuGet 패키지 매니저를 통해 MySQL Connector를 설치합니다.
[Tools] –> [NuGet Pacakage Manager] –> [Manage Nuget Packages for Solution…]
Browse 탭에서 MySql.Data 검색하고 추가


Entity Framework(EF) 을 사용하기 위해서는 Microsoft.EntityFrameworkCore와 Pomelo.EntityFrameworkCore.MySql을 마찬가지로 NuGet 매니저를 통해 설치합니다.



ADO.NET
개요
ADO.NET (ActiveX Data Objects for .NET)은 .NET 의 일부로 제공되는 데이터 접근 기술입니다.
이 기술은 다양한 데이터 소스 (주로 관계형 데이터베이스)와의 통신을 위해 설계되었으며, 데이터베이스 작업을 위한 연결, 명령, 데이터 읽기 및 데이터 셋 관리 기능을 제공합니다.
ADO.NET은 연결 지향 아키텍처를 기반으로 하며, 동시에 연결이 끊어진(disconnected) 환경에서도 데이터를 처리할 수 있는 기능을 갖추고 있습니다.
주요 구성 요소:
- Connection: 데이터 소스에 대한 연결을 관리합니다.
- Command: 데이터 소스에 대해 SQL 문을 실행합니다.
- DataReader: 연결 지향 방식으로 데이터를 읽어옵니다.
- DataAdapter: 데이터 셋(Data Set)과 데이터 소스(Data Source) 간의 데이터를 채우고 동기화합니다.
- DataSet: 데이터의 메모리 내 캐시를 유지하며, 데이터의 관계적 표현을 제공합니다.
예제들은 MySqlAdoNet 이라는 Class를 추가하여 진행하겠습니다.
Query vs NonQuery
Query와 NonQuery는 데이터베이스와 상호작용하는 SQL 명령문을 실행하는 두 가지 방법입니다. 각각의 차이점과 사용 용도를 간단하게 설명하겠습니다.
Query는 데이터베이스에서 데이터를 조회하는 데 사용됩니다. 주로 SELECT 문을 실행하여 결과 집합을 반환합니다.
- 반환값:
Query는 데이터베이스에서 데이터를 조회한 결과를 반환합니다. 결과는 보통 데이터 리더(DataReader)나 데이터 집합(DataSet) 형태로 반환됩니다. - 예시:
SELECT문을 실행하여 특정 테이블의 데이터를 조회할 때 사용됩니다. MySqlCommandClass method- ExecuteReader()
NonQuery는 데이터베이스의 데이터를 변경하거나 구조를 변경하는 명령문을 실행하는 데 사용됩니다. 주로 INSERT, UPDATE, DELETE 문 또는 데이터 정의 언어(DDL) 명령문(CREATE TABLE, ALTER TABLE 등)을 실행할 때 사용됩니다.
- 반환값:
NonQuery는 영향받은 행의 수를 반환합니다. 즉,INSERT,UPDATE,DELETE문이 영향을 미친 데이터베이스 행의 수를 반환합니다. DDL 명령문을 실행할 때는 보통 반환 값을 사용하지 않습니다. - 예시: 테이블에 데이터를 삽입하거나 기존 데이터를 수정 또는 삭제할 때 사용됩니다.
MySqlCommandClass method- ExecuteNonQuery()
Database 생성
생성자(Constructor)에서 Database가 없으면 Database를 생성하는 코드를 추가하였습니다.
Database가 있으면 연결 string을 _connectionString 변수에 저장합니다.
using MySql.Data.MySqlClient;
namespace UseDatabase.Repositories
{
public class MySqlAdoNet
{
private string _connectionString;
// dbName: devitworld_db, dbUserName: root, dbPassword: devitworld!!
public MySqlAdoNet(string dbName, string dbUserName, string dbPassword)
{
// Initial connection string without specifying a database
string initialConnectionString = $"server=localhost;user={dbUserName};password={dbPassword};";
// Check if the database exists, if not, create it
using (var connection = new MySqlConnection(initialConnectionString))
{
try
{
connection.Open();
var createDbCommand = new MySqlCommand($"CREATE DATABASE IF NOT EXISTS `{dbName}`;", connection);
createDbCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
throw new Exception("An error occurred while creating the database.", ex);
}
}
_connectionString = $"server=localhost;database={dbName};user={dbUserName};password={dbPassword};";
}
}Database 연결
_connectionString 에 저장한 string과 MySqlConnection을 이용하여, Database에 연결할 수 있습니다.
// connection test
public void TestConnection()
{
// _connectionString = $"server=localhost;database={dbName};user={dbUserName};password={dbPassword};";
using (MySqlConnection connection = new MySqlConnection(_connectionString))
{
try
{
connection.Open();
Console.WriteLine("Connection is successful.");
}
catch (Exception ex)
{
Console.WriteLine("Connection is failed.");
Console.WriteLine(ex.Message);
}
}
}Table 생성
다음과 같이 CREATE SQL 문을 활용하여 Table을 생성할 수 있습니다.
public void CreateUserTable()
{
string query = $"CREATE TABLE IF NOT EXISTS USER (ID INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(50), AGE INT, EMAIL VARCHAR(50));";
using (MySqlConnection connection = new MySqlConnection(_connectionString))
{
connection.Open();
using (MySqlCommand command = new MySqlCommand(query, connection))
{
command.ExecuteNonQuery();
}
}
Console.WriteLine("USER table created successfully.");
}CROUD
다음은 Ado.Net을 이용하여 MySQL 데이터베이스에서 CRUD(Create, Read, Update, Delete) 작업을 수행할 수 있고, 예제는 다음과 같습니다.
Create
SQL의 Insert 문과 MySqlCommand의 ExecuteNonQuery() Method을 활용하여 Data를 생성합니다.
public void InsertUser(string name, int age, string email)
{
string query = $"INSERT INTO USER (NAME, AGE, EMAIL) VALUES ('{name}', {age}, '{email}');";
using (MySqlConnection connection = new MySqlConnection(_connectionString))
{
connection.Open();
using (MySqlCommand command = new MySqlCommand(query, connection))
{
command.ExecuteNonQuery();
}
}
Console.WriteLine("USER inserted successfully.");
}Read
SQL의 Select 문과 MySqlCommand의 ExecuteReader() Method를 이용해 Data를 조회합니다.
public void ReadAllUsers()
{
string query = $"SELECT * FROM USER;";
using (MySqlConnection connection = new MySqlConnection(_connectionString))
{
connection.Open();
using (MySqlCommand command = new MySqlCommand(query, connection))
{
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine($"ID: {reader.GetInt32(0)}, NAME: {reader.GetString(1)}, AGE: {reader.GetInt32(2)}, EMAIL: {reader.GetString(3)}");
}
}
}
}
}Update
SQL의 Update 문과 MySqlCommand의 ExecuteNonQuery() Method을 활용하여 Data를 생성합니다.
public void UpdateUser(int id, string name, int age, string email)
{
string query = $"UPDATE"
+ $" USER"
+ $" SET"
+ $" NAME = '{name}',"
+ $" AGE = {age},"
+ $" EMAIL = '{email}'"
+ $" WHERE"
+ $" ID = {id};";
using (MySqlConnection connection = new MySqlConnection(_connectionString))
{
connection.Open();
using (MySqlCommand command = new MySqlCommand(query, connection))
{
command.ExecuteNonQuery();
}
}
Console.WriteLine("USER updated successfully.");
}Delete
SQL의 Delete 문과 MySqlCommand의 ExecuteNonQuery() Method을 활용하여 Data를 생성합니다.
public void DeleteUser(int id)
{
string query = $"DELETE FROM USER WHERE ID = {id};";
using (MySqlConnection connection = new MySqlConnection(_connectionString))
{
connection.Open();
using (MySqlCommand command = new MySqlCommand(query, connection))
{
command.ExecuteNonQuery();
}
}
Console.WriteLine("USER deleted successfully.");
}Test
다음과 같이 Main에 앞서 추가한 MySqlAdoNet Class를 활용하여 테스트 할 수 있습니다.
namespace UseDatabase
{
class Program
{
static void Main(string[] args)
{
MySqlAdoNet mySqlAdoNet = new MySqlAdoNet("devitworld_db", "root", "Devitworld!!!!");
mySqlAdoNet.TestConnection();
mySqlAdoNet.CreateUserTable();
mySqlAdoNet.InsertUser("devitworld", 36, "insfamworld@naver.com");
mySqlAdoNet.InsertUser("creamboy", 32, "creamboy1@naver.com");
mySqlAdoNet.ReadAllUsers();
mySqlAdoNet.UpdateUser(1, "devitworld", 37, "devitworld@google.com");
mySqlAdoNet.DeleteUser(mySqlAdoNet.GetUserId("creamboy"));
Console.WriteLine("Finish the Database Tutorial !!");
}
}
}Entity Framework
개요
Entity Framework (EF)는 Microsoft에 의해 개발된 객체 관계 매핑 (ORM) 프레임워크로, 데이터베이스 테이블을 .NET의 클래스로 매핑하여 개발자가 데이터베이스를 객체지향적으로 다룰 수 있도록 돕습니다.
EF를 사용하면 SQL 쿼리를 직접 작성하지 않고도 데이터베이스 작업을 할 수 있으며, 코드의 가독성과 유지 보수성이 향상됩니다.
Entity Framework의 주요 특징:
- 코드 중심 접근법(Code First): 데이터베이스 스키마를 .NET 클래스에서 정의한 후 EF가 이를 바탕으로 데이터베이스를 생성하고 관리합니다.
- 데이터베이스 중심 접근법(Database First): 기존의 데이터베이스를 기반으로 모델을 생성하고, 이 모델을 사용하여 데이터베이스와 상호작용합니다.
- 모델 중심 접근법(Model First): 개념적 모델을 먼저 설계하고 이를 바탕으로 데이터베이스 스키마와 코드를 생성합니다.
- LINQ(Language Integrated Query): 데이터베이스 쿼리를 .NET 언어의 일부처럼 표현할 수 있어 쿼리 작성이 쉽고 간편합니다.
주요 구성 요소
- DbContext: 데이터베이스와의 세션을 관리하고, 데이터베이스 작업을 수행하는 주요 클래스입니다.
- Entity: 데이터베이스의 테이블과 매핑되는 클래스입니다.
- DbSet: 특정 엔터티 유형의 컬렉션을 나타내며, 데이터베이스 작업을 수행할 수 있는 메서드를 제공합니다.
모델 정의
Database에 사용할 모델을 정의합니다.
namespace UseDatabase.Model
{
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
}
Database 연결
_connectionString 에 저장한 string과 OnConfiguring을 이용하여, Database에 연결할 수 있습니다.
OnConfiguring 메서드는 DbContext 클래스의 메서드 중 하나로, Entity Framework Core에서 데이터베이스 컨텍스트가 어떻게 설정되고 구성되는지를 정의합니다.
이 메서드는 주로 데이터베이스 연결 문자열과 옵션을 설정하는 데 사용됩니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UseDatabase.Model;
using Microsoft.EntityFrameworkCore;
namespace UseDatabase.Repositories
{
// Example class for Entity Framework with MySQL
public class MySqlEntityFramework : DbContext
{
public DbSet<User> User { get; set; }
private readonly string _connectionString;
public MySqlEntityFramework(string dbName, string dbUserName, string dbPassword)
{
_connectionString = $"server=localhost;database={dbName};user={dbUserName};password={dbPassword};";
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySql(_connectionString, new MySqlServerVersion(new Version(8, 0, 36)));
}
}
Table 생성
ntity Framework Core를 사용하면 기본적으로 모델 클래스의 이름과 같은 테이블을 자동으로 생성해줍니다.
이 기능은 Entity Framework Core의 Code First 접근 방식의 일부로, 데이터베이스 스키마가 코드에서 정의된 모델 클래스를 기반으로 자동으로 생성됩니다.
허나 다음과 같이 OnModelCreating()을 override 하여 필드에 추가 옵션을 제공할 수 있습니다.
// Create Table
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>(entity =>
{
entity.ToTable("User"); // 테이블 이름 설정
entity.HasKey(e => e.Id); // 기본 키 설정
entity.Property(e => e.Name)
.IsRequired() // 필수 필드
.HasMaxLength(50); // 최대 길이
entity.Property(e => e.Email)
.HasMaxLength(100); // 최대 길이
entity.Property(e => e.Age)
.IsRequired();
});
Console.WriteLine("Table Created !!");
}CROUD
다음은 EntityFramework을 이용하여 MySQL 데이터베이스에서 CRUD(Create, Read, Update, Delete) 작업을 수행할 수 있고, 예제는 다음과 같습니다.
Create
public void CreateUser(string name, int age, string email)
{
User user = new User
{
Name = name,
Age = age,
Email = email
};
User.Add(user);
SaveChanges();
}Read
public List<User> GetUsers()
{
return User.ToList();
}Update
SQL의 Update 문과 MySqlCommand의 ExecuteNonQuery() Method을 활용하여 Data를 생성합니다.
public void UpdateUser(int id, string name, int age, string email)
{
User user = User.Find(id);
if (user != null)
{
user.Name = name;
user.Age = age;
user.Email = email;
SaveChanges();
}
}Delete
SQL의 Delete 문과 MySqlCommand의 ExecuteNonQuery() Method을 활용하여 Data를 생성합니다.
// 4. Delete
public void DeleteUser(int id)
{
User user = User.Find(id);
if (user != null)
{
User.Remove(user);
SaveChanges();
}
}Test
다음과 같이 Main에 앞서 추가한 MySqlEntityFramework Class를 활용하여 테스트 할 수 있습니다.
namespace UseDatabase
{
class Program
{
static void Main(string[] args)
{
using (var mySqlEntityFramework = new MySqlEntityFramework("devitworld_db", "root", "Devitworld!!!!"))
{
mySqlEntityFramework.Database.EnsureCreated();
mySqlEntityFramework.CreateUser("devitworld", 36, "insfamworld@naver.com");
mySqlEntityFramework.CreateUser("creamboy", 32, "creamboy1@naver.com");
var users = mySqlEntityFramework.GetUsers();
foreach (var user in users)
{
Console.WriteLine($"Id: {user.Id}, Name: {user.Name}, Age: {user.Age}, Email: {user.Email}");
}
mySqlEntityFramework.UpdateUser(1, "devitworld", 37, "devitworld@google.com");
mySqlEntityFramework.DeleteUser(mySqlEntityFramework.GetUserId("creamboy"));
}
Console.WriteLine("Finish Entity Framework Examples !!");
}
}
}Dapper
개요
Dapper는 .NET 환경에서 사용할 수 있는 경량의 객체 관계 매핑 (ORM) 라이브러리입니다.
Stack Overflow 팀에 의해 개발되었으며, 그들의 필요에 따라 고성능을 중시하는 구조로 설계되었습니다.
Dapper는 ADO.NET 기술을 기반으로 하면서도, 개발자가 SQL 쿼리를 직접 작성할 수 있는 유연성을 제공하며, 이 쿼리 결과를 객체로 쉽게 매핑할 수 있도록 돕습니다.
Dapper는 많은 개발자들에게 성능이 중요한 애플리케이션에서 널리 사용되고 있습니다.
Dapper의 주요 특징:
- 성능: Dapper는 매우 빠른 실행 속도를 제공합니다. 이는 내부적으로 데이터베이스 쿼리 결과를 객체로 매핑할 때 최적화된 처리가 이루어지기 때문입니다.
- 간결성: SQL 쿼리를 직접 작성하므로, 복잡한 쿼리나 특정 데이터베이스 기능을 사용하는데 있어 제한이 없습니다.
- 확장성: Dapper는 확장 메서드를 통해 기능을 제공하므로, 개발자는 필요한 기능을 선택적으로 사용할 수 있습니다.
- 간편한 설정: Dapper는 별도의 설정 파일이나 복잡한 코드 구성 없이 사용할 수 있으며, 단 몇 줄의 코드로 시작할 수 있습니다.
참고 링크
- My Git Repository (devitworld-csharp-basic) – DevitworldConsoleApp/8_Database










