Dapper.Rainbow를 사용하여 탐색 속성으로 개체를 삽입하고 업데이트하는 방법 (또는 선택적으로 Dapper.Contrib 사용)

dapper dapper-rainbow micro-orm orm

문제

나는 최근에 Dapper를 조사하기 시작했습니다. 나는 그것을 테스트하고 있으며 기본 CRUD를 할 수 있었고 기본적인 의미는 다음과 같은 구조를 가진 클래스에서 작업하는 것입니다.

public class Product {
    public int Id {get;set;}
    public string Name {get;set;}
}

이제 삽입 및 업데이트를 더 쉽게 수행 할 수있는 Dapper.Rainbow를 찾을 수있는 무언가를 찾고있었습니다. 나는 그것을 체크하고 위에서 설명한대로 오브젝트를 가져 와서 삽입하는데 사용할 수 있었다. 내 문제는 Product 에 탐색 속성이있을 때 해당 필드에 삽입을 할 수 없다는 것입니다. 그래서 내가 이것을 가지고 있다면 :

public class Product {
    public int Id {get;set;}
    public string Name {get;set;}
    public ProductCategory Category {get;set;}
}

나는 이것을 할 수 없을 것이다 :

// connection is a valid and opened connection            
 var db = TestDatabase.Init(connection , 300);
 var newId = db.Products.Insert(newProduct);

이 이유 때문에

The member Category of type ProductCategory  cannot be used as a parameter value

Categoryint 형식 (데이터베이스의 동일한 데이터 형식)으로 바꾸면 문제가 해결 될 수 있습니다. 그러나 그렇게하면 (카테고리) ID 이상의 카테고리 정보로 제품을 쿼리 할 수 ​​없습니다.

원시 Dapper를 사용하지 않고 탐색 속성이있는 클래스를 사용하여 삽입 및 업데이트를 수행하려면 어떻게해야합니까? 다음을 수행하고 Dapper.Rainbow에 삽입하거나 업데이트 할 때 Category 를 무시하도록 알려 주길 바랬습니다.

public class Product {
    public int Id {get;set;}
    public string Name {get;set;}
    public ProductCategory Category {get;set;}
    public int CategoryId {get;set;} // this will be the same field name in the database
}

이 시나리오는 NHibernate에서 Category 의 프록시 객체를 가질 수 있고 그것을 Product 할당하고 저장할 수 있으며 매핑이 완벽하게 작동합니다. 그러나 나는 Dapper를 사용하는 것을 좋아합니다. 그래서 나는 탐구하고 있으며 이런 일이 어떻게 행해지는지 배우고 싶습니다.

수락 된 답변

Dapper와 함께하지 않습니다.

Dapper.Rainbow 는 현재 형태로는 불가능하지만 github에서 내 풀 요청을 하면 가능합니다.

아무도 Dapper.Contrib 을 사용 Dapper.Contrib 제안을 한 것이 Dapper.Contrib . 기능이 Rainbow에 있는지 묻습니다. 그러나 나는 아무도이 진술 (특히 굵은 글씨)을 알아 채지 않을 것이라고 기대하지 않았다.

이제 삽입 및 업데이트를 더 쉽게 수행 할 수있는 Dapper.Rainbow를 찾을 수있는 무언가를 찾고 있었습니다. 나는 그것을 체크하고 위에서 설명한대로 오브젝트를 가져 와서 삽입하는데 사용할 수 있었다. 내 문제는 제품에 탐색 속성이있을 때 해당 필드에 삽입을 할 수 없다는 것입니다 .

... 이미 Dapper 라이브러리에있는 대안 인 대안을 제안하십시오. 내 질문에 분명해야하고 솔루션이 github 에있는 전체 Dapper 라이브러리 에 있는지 여부를 명시 적으로 질문해야합니다. 그래서 도서관에서 더 많은 파기를 한 후에 나는 내 문제에 대한 지원이 있다는 것을 알게되었습니다.

Dapper.Contrib에 대한 경로

더 많은 것을 필요로 할 때까지 모두 내 프로젝트와 Rainbow 에서 잘 작동합니다. 그 안에 많은 들판이있는 테이블이 있어요. 방금 무지개를 내 물건에 공급하면 모든 필드가 업데이트됩니다. 모두 좋지는 않습니다. 하지만 그로 인해 배에서 빨리 뛰어 나와 NH로 돌아 가지 않습니다. 그래서 내 자신의 change tracking 구현하기 전에 누군가가 이미 좋은 일을했다면 바퀴를 다시 발명하고 싶지 않다. 나는 주위를 인터넷 검색 하고이 SO 스레드를 발견했다 . 이 스레드는 Rainbow 가 변경 추적을 지원하지 않는다는 사실을 확인했지만 다른 동물이 있으며 Dapper.Contrib 이라고 Dapper.Contrib . 그래서 저는 그것을 실험하기 시작했습니다.

그래서 우리는 다시 만난다.

ProductCategory 유형의 멤버 범주를 매개 변수 값으로 사용할 수 없습니다.

Rainbow 와 같은 문제가 있습니다. Contrib 가 탐색 속성을 지원하지 않습니다!? 나는 Dapper 와 함께 시간을 낭비하고 있다고 느껴지기 시작했고, 내가 제공하는 공연은 대단히 유익한 생각이었습니다. 까지...

WriteAttribute가 구조에 왔습니다 ...

이 클래스는 Dapper.Contrib 프로젝트에 포함 된 SqlMapperExtensions.cs 파일에 있습니다. 이 클래스에 대한 문서를 찾지 못했고 쉽게 찾을 수 있고 내게 큰 소리로 말하고 hey I'm the one you're looking for 이라고 말하는 어떤 의견도 없습니다. 위에서 설명한 것처럼 Rainbow를 제쳐 놓았을 때 나는 이것을 발견했습니다.

이 클래스의 사용법은 IgnorePropertyAttribute 를 사용했을 때와 동일합니다. 클래스 속성을 꾸밀 수있는 속성입니다. Dapper 가 생성 한 sql 포함시키지 않으려는 속성을이 특성으로 Dapper 합니다. 그래서 제 예제에서 Dapper에게 Category 필드를 제외 시키라고 말하면서이 작업을 수행해야했습니다.

public class Product {
    public int Id {get;set;}

    public string Name {get;set;}

    [Write(false)] // tell Dapper to exclude this field from the sql
    public ProductCategory Category {get;set;}

    public int CategoryId {get;set;}
}

나는 거의 다 왔어.

내가 Contrib 들어가는 이유는 change tracking 기능 때문입니다. 이 SO 스레드 ( 위의 링크와 동일)는 변경 내용 추적을 위해 클래스 인터페이스를 가지고 Contrib 와 함께 사용해야한다고 명시합니다. 따라서 필자의 예제 수업에서는 다음과 같이해야합니다.

public interface IProduct {
    int Id {get;set;}
    string Name {get;set;}
    ProductCategory Category {get;set;}
    int Category {get;set;}
}

// and implement it on my Product class
public class Product : IProduct {
    public int Id {get;set;}

    public string Name {get;set;}

    [Write(false)]
    public ProductCategory Category {get;set;}

    int Category {get;set;}
}

그게 거의다고 생각 했어! Dapper 가 전혀 신경 쓰지 않는다면 내 인터페이스에서 Category 를 정의해야하는 이유를 묻고있을 것입니다. 사실 그것은 단지 문제를 일으킬 것이고, 나는 그 문제를 해결할 것입니다.

필자의 특정 시나리오에서는 Product 객체에 대한 변경 내용 추적을 유지하면서 Category 필드에서 작업해야하는 경우가 있습니다. 추적 기능을 유지하려면 get 호출에 다음과 같은 인터페이스 유형을 제공해야합니다.

var product = connection.Get<IProduct>(id);

그 호출로 나는 액세스 할 수 없을Category 내 인터페이스를 정의하지 않을 경우 필드. 하지만 인터페이스에 정의하면 익숙한 오류가 발생합니다.

{type} 유형의 {member} 멤버를 매개 변수 값으로 사용할 수 없습니다.

정말 다시? 이걸 멈추게 해줘.

판결

클래스에 대해했던 것처럼 인터페이스 멤버를 꾸미면 해결하기가 쉽기 때문에 걱정할 필요가 없습니다. 따라서 모든 것을 작동하게하는 최종 구성은 다음과 같아야합니다.

public interface IProduct {
    // I will not discuss here what this attribute does
    // as this is documented already in the github source.
    // Just take note that this is needed,
    // both here and in the implementing class.
    [Key]
    int Id {get;set;}

    string Name {get;set;}

    [Write(false)]
    ProductCategory Category {get;set;}

    int Category {get;set;}
}

// and implement it on my Product class
public class Product : IProduct {
    [Key]        
    public int Id {get;set;}

    public string Name {get;set;}

    [Write(false)]
    public ProductCategory Category {get;set;}

    int Category {get;set;}
}

change tracking 기능이있는 Contrib 로 작업하려는 경우이 방법을 사용할 수 있습니다. Rainbow 와 함께 작업하고 싶었던 것과 같이 네비게이션 속성에 문제가 있는 경우 내 풀 요청 을 수행 할 수 있습니다 . WriteAttribute 와 같은 방식으로 Rainbow 작동합니다.

속성으로 클래스를 꾸미는 팬이 아니라면 확장 프로젝트는 모두 당신을위한 것이 아닙니다. 난 당신이 유창 형 구성의 일종으로 할 수 있도록 또 다른 확장 프로젝트가 있다는 것을 알고 있지만, 그것은 (의 핵심 부분으로 포함되지 않음)로 이동하지 않는 Dapper github에있는 라이브러리입니다. 핵심 라이브러리와 만 작업 할 수있는 나의 환경 설정은 전체 라이브러리를 조사하고 이미 존재하는지 또는 내 요구를 충족시키기 위해 향상시킬 수 있는지를 유도합니다. 그리고 그것은 RainbowContrib 모두를 위해 여기에서 설명하고 설명했습니다.

이 공헌, 내가 추가 한 매우 간단한 수업, 내가 제시 한 구성 요령, 그리고 그것들을 이끌어내는 시나리오가 Dapper를 사용하고자하는 미래의 누군가를 도울 것이며, 그것이 내가 갖고있는 것과 비슷한 설정을 갖기를 바랍니다. 또한,이 대답은 Dapper가 할 수있는 것과 수행 할 수없는 것의 더 많은 것을 devs에게 교육 할 것입니다. Dapper 라고 불리는 위대한 도구 는 더 나은 위키를 가질 자격이 있으며, 이 답변 / 여기에있는 기사가 작은 방법으로도 도움이되기를 바랍니다.


** 그리고 만약 내가 여기에 쓴 것이 이미 어딘가에 쓰여 있다면, 나는 2 주 동안 나는 대답을 기다리고있는 것을 발견하지 못했다. 그러면 누군가가 나를 그것에 연결시키는 것이 기쁠 것이다. 그것은 2 주 지금이고 내 질문에 보였 29 사람이 어떤 링크 또는 솔루션을 제안하지 않았으므로 여기에 공유 정보가 Dapper *에 새로운 것이라고 가정합니다 :)

참고 : 다른 사람들이 문제에 대한 잠재적 솔루션을 볼 수 있도록 내 질문 제목을 수정했습니다. 새로운 제목은 내가 Dapper에 대해 얻은 새로운 지식을 기반으로합니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.