대용량의 데이터를 한 번에 입력, 수정, 삭제할 때 대부분의 개발자는 ‘for’와 같은 루프 문을 사용하여 이를 처리하는 데 처리할 ‘row’의 개수만큼 operation이 발생하므로 RDBMS가 SQL Server의 경우 Bulk Operation 기법을 사용하여 한 번에 처리하도록 해야 한다. 또는 Table 변수를 사용하여 한 번에 모든 데이틀 넘겨주고 데이터베이스에서는 이를 한 번의 로직으로 처리하도록 유도해야 한다(ASP.NET MVC, Delete Multiple Rows With Checkbox).
소스 예제는 ‘Thumb IKR - Programming Examples’의 유튜브 강좌를 참고하였고 일부 소스는 수정하였다. VS2019에서 ASP.NET Core 웹 애플리케이션(MVC) 프로젝트를 생성하고 기본값을 그대로 사용하였으며 변경된 부분의 코드 위주로 아래에 소소를 나열하였다. 추가한 nuget package는 RepoDb.SqlServer와 RepoDb.SqlServer.BulkOperations이다(repodb.net).
{
"ConnectionStrings": {
"testdb": "Server=아이피주소;Database=디비;User Id=아이디;Password=패스워드;"
}
}
namespace BulkCRUD.Models
{
public class Student
{
public int StudentID { get; set; }
public string Name { get; set; }
public string Roll { get; set; }
}
}
특정 클래스의 인스턴스 하나만 생성되도록 하고 전체 애플리케이션에 대해 해당 인스턴스에 대한 간단한 글로벌 액세스를 제공해야 하는 경우 Singleton 패턴을 사용할 수 있다. 이번 예제에서는 심플하게 사용할 수 있는 예제를 ‘The Singleton Design Pattern - Part of the Gang of Four’ - IAmTimCorey 유튜브 강좌에서 참고하여 정리하여 보았다.
using System;
namespace ConsoleUI
{
internal class Program
{
private static readonly TableServers Host1List = TableServers.GetTableServers();
private static readonly TableServers Host2List = TableServers.GetTableServers();
private static void Main()
{
for (var i = 0; i < 5; i++)
{
Host1GetNextServer();
Host2GetNextServer();
}
}
private static void Host1GetNextServer()
{
Console.WriteLine("Next Server 1 : " + Host1List.GetNextServer());
}
private static void Host2GetNextServer()
{
Console.WriteLine("Next Server 2 : " + Host2List.GetNextServer());
}
}
}
프로그래밍 언어인 Rust와 C#을 OOP 관점에서 비교해 보았다. Rust는 OOP라기보다는 모듈/함수 지향형 프로그래밍 언어라고 보는 게 더 합당하다고 생각한다. What does “Rust & OOP” mean to you?
struct Door {
is_open: bool,
}
trait Openable {
fn new(is_open: bool) -> Door;
fn open(&mut self);
fn foo1(txt: &str);
fn foo2(&mut self);
}
impl Openable for Door {
fn new(is_open: bool) -> Door {
Door { is_open: is_open }
}
fn open(&mut self) {
self.is_open = true;
}
fn foo1(txt: &str) {
println!("{} {}", "Print foo ...", txt);
}
fn foo2(&mut self) {
Self::foo1("2");
}
}
fn main() {
let mut door = Door::new(false);
println!("{}", if door.is_open { "참" } else { "거짓" });
door.open();
println!("{}", if door.is_open { "참" } else { "거짓" });
Door::foo1("1");
door.foo2();
}