give me a crash course on
@https://github.com/phnx47/dapper-repositories
use mermaid diagrams and markdown tables
use gitmvp mcp
실행결과
실행 결과값
현재 레포 내용을 빠르게 스캔해 정확한 사용법과 최신 구조를 정리하겠습니다. 다 읽은 뒤, 한국어로 짧고 실전 위주의 크래시 코스를 Mermaid 다이어그램과 표로 정리해 드립니다.
빠르게 레포 주요 파일을 더 읽어 실전 예제를 정확히 제시할 수 있게 하겠습니다. CRUD, 조인, 필터 체이닝 관련 메서드 시그니처를 동시에 확인합니다.
MicroOrm.Dapper.Repositories 크래시 코스
한눈에 보기
목적: POCO + Attribute 메타데이터로 SQL을 자동 생성해 Dapper CRUD/조회/조인/페이지네이션을 간결화
핵심 구성: DapperRepository<TEntity>, ReadOnlyDapperRepository<TEntity>, ISqlGenerator<TEntity>, DapperDbContext, Attribute 세트(Join/Identity/Status/Deleted/UpdatedAt)
graph LR
A[POCO Entity<br/>DataAnnotations + MR Attributes] --> B[ISqlGenerator<TEntity><br/>SQL 생성]
B --> C[DapperRepository<TEntity><br/>CRUD/조회 API]
C --> D[Dapper(IDbConnection)]
D --> E[(DB)]
C -.필터 체이닝.-> F[FilterData<br/>Select/Order/Limit/Group]
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using MicroOrm.Dapper.Repositories.Attributes;
using MicroOrm.Dapper.Repositories.Attributes.LogicalDelete;
using MicroOrm.Dapper.Repositories.Attributes.Joins;
[Table("Orders")]
public class Order
{
[Key] [Identity] public int Id { get; set; } // 자동증가 키
public int CustomerId { get; set; }
[Status] public OrderStatus Status { get; set; } // 논리삭제 상태 컬럼
[UpdatedAt] public DateTime? UpdatedAt { get; set; } // Update/Insert 시 자동 갱신
// 조인: 현재 테이블의 FK(CustomerId) → 외부 PK(Id)
[InnerJoin("Customers", "CustomerId", "Id")]
public Customer Customer { get; set; } = default!;
}
public enum OrderStatus
{
Active = 0,
[Deleted] Deleted = 1 // 논리삭제 값 지정
}
리포지토리 사용(기본 CRUD)
using (var repo = new DapperRepository<Order>(connection))
{
// Insert (Identity 컬럼이면 반환된 키를 엔티티에 세팅)
await repo.InsertAsync(new Order { CustomerId = 1, Status = OrderStatus.Active });
// Update (명시 필드만 업데이트하려면 includes 사용)
await repo.UpdateAsync(order, x => x.Status);
// Delete (논리삭제면 Status/UpdatedAt만 갱신)
await repo.DeleteAsync(order);
// 조회
var one = await repo.FindAsync(x => x.CustomerId == 1);
var all = await repo.FindAllAsync(x => x.Status == OrderStatus.Active);
// 범위 조회(BETWEEN)
var range = await repo.FindAllBetweenAsync(DateTime.UtcNow.AddDays(-7), DateTime.UtcNow, x => x.UpdatedAt!);
// 카운트/Distinct 카운트
var total = await repo.CountAsync(x => x.Status == OrderStatus.Active);
var distinct = await repo.CountAsync(x => x.CustomerId);
}
조인 포함 조회
// 단건 + 조인
var withJoin = repo.Find<Order>(
x => x.Id == someId,
x => x.Customer
);
// 다건 + 조인
var listWithJoin = repo.FindAll<Order>(
x => x.Status == OrderStatus.Active,
x => x.Customer
);
sequenceDiagram
participant R as ReadOnlyDapperRepository
participant G as SqlGenerator<TEntity>
participant D as Dapper/IDbConnection
R->>G: GetSelect(..., includes: Customer)
G-->>R: SELECT ... INNER JOIN Customers ...
R->>D: Query(sql, params)
D-->>R: IEnumerable<TEntity> (멀티매핑)
페이징/정렬/프로젝션(필터 체이닝)
using MicroOrm.Dapper.Repositories.SqlGenerator.Filters;
var paged = await repo
.SetSelect<Order>(o => new { o.Id, o.UpdatedAt }) // SELECT 컬럼 축소
.SetOrderBy<Order>(OrderInfo.SortDirection.DESC, false, o => o.UpdatedAt!) // ORDER BY
.SetLimit(20, 0) // LIMIT/OFFSET (MSSQL은 ORDER 필수)
.FindAllAsync(o => o.Status == OrderStatus.Active);
벌크 작업
await repo.BulkInsertAsync(orders); // MSSQL: 2099 파라미터 제한 자동 분할
await repo.BulkUpdateAsync(orders); // Oracle: MERGE INTO 생성
트랜잭션/컨텍스트
using MicroOrm.Dapper.Repositories.DbContext;
public class AppDbContext : DapperDbContext
{
public AppDbContext(IDbConnection conn) : base(conn) { }
}
using var ctx = new AppDbContext(connection);
using var tx = await ctx.BeginTransactionAsync();
var repoTx = new DapperRepository<Order>(ctx.Connection);
await repoTx.InsertAsync(order, tx);
tx.Commit();
주요 타입 요약
타입/어트리뷰트
용도
DapperRepository<TEntity>
CRUD, Bulk, 조인 포함 조회 제공
ReadOnlyDapperRepository<TEntity>
읽기 전용 API(Find/FindAll/Count/Between 등)
ISqlGenerator<TEntity>
속성/Attribute 메타데이터로 SQL 생성
DapperDbContext
연결 열기/트랜잭션 시작 유틸
[Identity]
자동 증가 키
[UpdatedAt]
SQL 생성 시 시간 자동 세팅(UTC 기본, OffSet 지원)
[Status] + [Deleted]
논리삭제: bool/bool? 또는 Enum + Deleted 멤버
[InnerJoin/LeftJoin/RightJoin]
조인 메타데이터(테이블/키/스키마/별칭)
[IgnoreUpdate]
UPDATE SET 제외
자주 쓰는 메서드
메서드
설명
Insert/InsertAsync
Identity 반환/대입 포함
Update/UpdateAsync
includes로 부분 업데이트 지원
Delete/DeleteAsync
논리삭제면 Status/UpdatedAt만 변경
Find/FindAll/FindById
기본/조인 포함 오버로드 다양
FindAllBetween
BETWEEN 조회(문자열 또는 DateTime 포맷)
Count
기본/Distinct 카운트
SetSelect/SetOrderBy/SetLimit
SELECT/ORDER BY/LIMIT 체이닝(한 번성/영구 플래그)
프로바이더별 Identity 반환
Provider
Insert 후 키 반환
MSSQL
SELECT SCOPE_IDENTITY()
MySQL
SELECT CONVERT(LAST_INSERT_ID(), SIGNED INTEGER)
SQLite
SELECT LAST_INSERT_ROWID()
PostgreSQL
RETURNING Id
Oracle
RETURNING Id INTO :newId
베스트 프랙티스
엔티티 키/컬럼은 Key, Column, Table(DataAnnotations)로 명시
논리삭제는 [Status] 컬럼 + bool/bool? 또는 Enum의 [Deleted] 멤버 사용
MSSQL 페이징은 반드시 SetOrderBy 후 SetLimit
조인은 엔티티 내 내비게이션 속성에 Join Attribute 지정 후, includes 전달
대량 작업은 BulkInsert/BulkUpdate 우선 고려
Clean Architecture 연계(요약)
Domain: 엔티티 + DataAnnotations(외부 의존 최소), Join/Status/UpdatedAt Attribute는 규칙에 맞춰 도입 여부 결정
Infrastructure: DapperRepository<TEntity> 구현/주입, SQLProvider 전역 설정
Application: CQRS 핸들러에서 리포지토리 인터페이스 사용
Presentation: MediatR 통해 호출
빠른 스타터 코드 스니펫
// 1) 설정
MicroOrmConfig.SqlProvider = SqlProvider.MSSQL;
// 2) 리포지토리
using var repo = new DapperRepository<Order>(connection);
// 3) CRUD
await repo.InsertAsync(new Order { CustomerId = 1, Status = OrderStatus.Active });
var page = await repo.SetOrderBy<Order>(OrderInfo.SortDirection.DESC, false, x => x.UpdatedAt!).SetLimit(10).FindAllAsync(x => x.Status == OrderStatus.Active);
주요 파일 참고(최신): IDapperRepository.cs, DapperRepository.*.cs, ReadOnlyDapperRepository.*.cs, SqlGenerator/*, Attributes/*, DbContext/DapperDbContext.cs