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
 










