재우니의 블로그

MicroOrm.Dapper.Repositories

 

 

 

코드가 빠르게 실행되는 것을 좋아한다면 Micro ORM에 대해 알고 있을 것입니다. 그것들은 간단하고 주요 목표 중 하나는 데이터 저장소에서 SQL 문장을 가장 빠르게 실행하는 것입니다. 일부 Micro ORM의 경우 고유한 SQL 문장을 작성해야 하며 이것이 가장 인기 있는 Micro ORM Dapper 의 경우입니다.

 

이 도구는 각 C# POCO 클래스 "메타데이터"를 기반으로 하는 CRUD 작업에 대한 SQL 문장 생성을 추상화합니다. 우리는 이러한 작업의 실행을 구현하는 두 Micro ORM용 플러그인이 있다는 것을 알고 있지만 바로 이 도구가 다른 점입니다.

 

 "SQL 생성기"는 정의 및 SQL 생성기를 재정의할 수 있는 가능성 및 각 문장을 작성하는 방식에 따라 POCO 클래스에 대한 모든 CRUD 문장을 생성하는 일반 구성 요소입니다. 원래 아이디어는 Yoinbol 에서 가져왔습니다 .

 

 

메타데이터 속성

 

[Key]
From System.ComponentModel.DataAnnotations- 기본 키에 사용합니다.

 

[Identity]
ID 키에 사용합니다.

 

[Table]
From System.ComponentModel.DataAnnotations.Schema- 기본적으로 데이터베이스 테이블 이름은 모델 이름과 일치하지만 이것으로 재정의할 수 있습니다.

 

[Column]
From System.ComponentModel.DataAnnotations.Schema- 기본적으로 열 이름은 속성 이름과 일치하지만 이것으로 재정의할 수 있습니다.

 

[NotMapped]
From System.ComponentModel.DataAnnotations.Schema- 해당 열이 없고 SQL 생성기에서 무시해야 하는 "논리적" 속성의 경우.

 

[Deleted], [Status]
물리적 삭제 대신 "논리적 삭제"를 구현하는 테이블의 경우. bool이를 사용하여 enum 을 적용합니다.

 

[LeftJoin]
속성에 대한 왼쪽 조인: 컬렉션 및 개체가 지원됩니다.

 

[InnerJoin]
속성에 대한 내부 조인: 컬렉션 및 개체가 지원됩니다.

 

[RightJoin]
속성에 대한 오른쪽 조인: 컬렉션 및 개체가 지원됩니다.

 

[CrossJoin] - SQLite 전용
속성에 대한 교차 조인: 컬렉션 및 개체가 지원됩니다.

 

[UpdatedAt]
삽입 및 업데이트에 대해 DataTime.UtcNow(로컬 날짜를 사용하거나 오프셋을 정의할 수 있음)를 자동으로 설정합니다.

 

 

메모

  • 기본적으로 SQL 생성기는 POCO 이름을 테이블 이름과 매핑하고 각 공용 속성을 열에 매핑합니다.
  • 특정 POCO에 [Deleted]를 사용하면 해당 문장은 삭제가 아닌 업데이트가 됩니다.
  • 복잡한 기본 키를 지원합니다.
  • 단순 조인을 지원합니다.
  • 이 순간 MSSQL에서는 OrderBy를 먼저 호출하는 경우에만 오프셋과 함께 limit을 사용할 수 있습니다. 그렇지 않으면 limit이 무시됩니다.
  • Oracle에서 dapper와 함께 GUID를 사용하려고 하면 문제가 있습니다. 이 경우 작동하지 않습니다. 자세한 내용은 DapperLib/Dapper#633 DapperLib/Dapper#637 vauto/Dapper.Database#1 참조

 

사용법

 

"Users" POCO:

[Table("Users")]
public class User
{
    [Key, Identity]
    public int Id { get; set; }

    public string ReadOnly => "test"; // because don't have set

    public string Name { get; set; }

    public int AddressId { get; set; }

    [LeftJoin("Cars", "Id", "UserId")]
    public List<Car> Cars { get; set; }

    [LeftJoin("Addresses", "AddressId", "Id")]
    public Address Address { get; set; }

    [Status, Deleted]
    public bool Deleted { get; set; }

    [UpdatedAt]
    public DateTime? UpdatedAt { get; set; }
}

"Cars" POCO:

[Table("Cars")]
public class Car
{
    [Key, Identity]
    public int Id { get; set; }

    public string Name { get; set; }

    public byte[] Data { get; set; }

    public int UserId { get; set; }

    [LeftJoin("Users", "UserId", "Id")]
    public User User { get; set; }

    [Status]
    public StatusCar Status { get; set; }
}

public enum StatusCar
{
    Inactive = 0,

    Active = 1,

    [Deleted]
    Deleted = -1
}

Example Implements the simple repository:

public class UserRepository : DapperRepository<User>
{
    public UserRepository(IDbConnection connection, ISqlGenerator<User> sqlGenerator)
        : base(connection, sqlGenerator)
    {

    }
}

 

 

Queries

 

 

Find by ID:

var user = await userRepository.FindAsync(x => x.Id == 5);

Query with limit:

var limit = 10u;
var users = await userRepository.SetLimit(limit).FindAllAsync();

Query with limit and offset:

var limit = 10u;
var offset = 5u;
var users = await userRepository.SetLimit(limit, offset).FindAllAsync();

Query with OrderBy:

var users = await userRepository.SetOrderBy(OrderInfo.SortDirection.DESC, x => x.CreatedAt).FindAllAsync();

Query with SetSelect:

var users = await userRepository.SetSelect(x => new {x.Id, x.Name}).FindAllAsync();

Find all users for AccountId equals to 3 and not logical deleted:

var allUsers = await userRepository.FindAllAsync(x => x.AccountId == 3 && x.Deleted != false);

 

 

 

Example with Asp.Net Core and D.I

 

 

Configure Services

//Your DB Provider
MicroOrmConfig.SqlProvider = SqlProvider.MySQL;
//Not required
MicroOrmConfig.TablePrefix = "db1_";
//Add generic SqlGenerator as singleton
services.AddSingleton(typeof(ISqlGenerator<>), typeof(SqlGenerator<>));
//Your db factory
services.AddSingleton<IDbConnectionFactory, DbFactory>(x => new DbFactory(appSettings.DbConnectionString));

 

 

Example implements BaseRepository with IDbConnectionFactory

public class BaseRepository<T> : DapperRepository<T> where T : class
{
    private readonly IDbConnectionFactory _factory;
    public BaseRepository(IDbConnectionFactory factory, ISqlGenerator<T> generator)
        : base(factory.OpenDbConnection(), generator)
    {
        _factory = factory;
    }
        
    protected IDbConnection GetConnection()
    {
        return _factory.OpenDbConnection();
    }
 }

 

 

MicroOrm.Dapper.Repositories

 

https://github.com/phnx47/dapper-repositories

 

GitHub - phnx47/dapper-repositories: CRUD for Dapper

CRUD for Dapper. Contribute to phnx47/dapper-repositories development by creating an account on GitHub.

github.com

 

MicroOrm.Pocos.SqlGenerator

 

https://github.com/ElNinjaGaiden/MicroOrm.Pocos.SqlGenerator

 

GitHub - ElNinjaGaiden/MicroOrm.Pocos.SqlGenerator: Tool for auto generation of CRUD sql statements based on entities definition

Tool for auto generation of CRUD sql statements based on entities definitions - GitHub - ElNinjaGaiden/MicroOrm.Pocos.SqlGenerator: Tool for auto generation of CRUD sql statements based on entities...

github.com