1

나는 microorm으로 PetaPoco와 함께 .Net에서 N 계층 솔루션을 가지고 있습니다. PetaPoco의 템플릿 생성기에서 생성 된 엔티티를 얻습니다. 이 엔티티 T은 기본 클래스 Record<T>에서 파생됩니다. 그런 다음 데이터 액세스 기능을 추가하고 Save()Delete() 메서드를 추가하여 Record<T> 기본 메서드를 재정의합니다..net 일반 저장소 문제 petapoco

엔티티 (이 방법은 내가 전화를 걸) 나는 일반 저장소를 만들 때

public partial class Document : Record<Document> 
{ 
    public new int Delete() 
    { 
     int rowsAffected; 
     using (var uow = DB.GetInstance().GetTransaction()) 
     { 
      rowsAffected = base.Delete(); 
      LogSystem("Deleting", "Deleting a document", 0, 0, GUID); 
      uow.Complete(); 
     } 
     return rowsAffected; 
    } 
} 

그런 다음 호출하기 방법은 기본 클래스 Record<T> 아니라 내 사용자 지정 것들 출신의 오버라이드 Delete 방법은 다음과 엔티티에서 entityRepository.Delete() 메서드를 호출하면 내 엔터티의 Delete() 메서드가 호출되고 기본 Record<T> 클래스의 메서드가 호출되지 않아야합니다.

일반 저장소 클래스는 follwos과 같습니다

public abstract class GenericRepository<T> : IGenericRepository<T> where T : Record<T>, new() 
{ 
    public void Delete(T entity) 
    { 
     entity.Delete(); 
    } 
} 
+0

가 DapperExtensions 내 대답을 참조하십시오. PetaPoco를 사용하더라도 다른 것들은 비슷해야합니다. https://stackoverflow.com/a/45460483/5779732 –

+0

안녕하세요, 답장을 보내 주셔서 감사합니다. 이미이 질문을 살펴 봤지만 엔티티의 우선 적용 메소드를 호출하는 방법에 대한 답변은 제공하지 않습니다. 기본 클래스. 또한 UoW 패턴을 통합하는 방법을 알지 못합니다. 사용하는 것이 좋지만 PetaPoco 트랜잭션인데, 위와 같이 사용해야하는지 모릅니다. –

+0

또한 어떤 디자인 입력을 찾고 있어요 –

답변

0

이 문제의 원인은 GenericRepository에 T를 "레코드에서 파생되는 것"으로 지정했기 때문입니다. 이것은 단지 T.

가능한 모든 인스턴스에 대해 한 번 수행되기 때문에 그래서 wenn entity.Delete()를 호출이 호출은 당신이 Record<T> 클래스에 액세스 할 수있는 경우, 단지 가상 Delete() 방법을 그것을 무시,이 기본 방법으로 연결됩니다 Document.

되지 않은 경우,이 같은 것을 사용해보십시오 :

public class ExtendedRecord<T>: Record<T> 
{ 
    public virtual new int Delete() 
    { 
    base.Delete(); 
    } 
} 

public partial class Document : ExtendedRecord<Document> 
{ 
    public override int Delete() 
    { 
    // ... 
    } 
} 

public abstract class GenericRepository<T> : IGenericRepository<T> 
    where T : ExtendedRecord<T>, new() 
{ 
    // ... 
} 
+0

이 답변은 "솔루션 3 :"입니다. –

+0

마지막으로 Record 클래스의 메서드를 재정의하지 않기로 결정했습니다. 대신 Logging 로직을 저장소로 옮긴다. 모두에게 감사드립니다. –

0

고백 : 나는 더 PetaPoco의 지식과 템플릿 생성이 없습니다.

문제는 PetaPoco IMHO보다 OO (구체적으로 상속)와 관련이 있습니다. generic 리포지토리가 각 엔터티의 기본 클래스 인 Record<T>으로 생성 된 경우 예상대로 수행됩니다. 수업의 상속을 면밀히 조사해야합니다.

아래에서 ORM 기능과 일치시키기 위해 제안한 솔루션을 약간 변경해야 할 수도 있습니다.

해결 방법 1 :

아래처럼 기본 클래스 또는 인터페이스 뭔가 새로운 선언 :

public interface IEntityBase{..... 

인터페이스에서 Delete 방법 등 필요한 회원을 포함합니다. 그런 다음

는 물론이 인터페이스에서 각 엔티티를 도출 :

public partial class Document : Record<Document>, IEntityBase 

다음, 대신 다음과 같은 Record<T>뭔가의 인터페이스로 일반적인 저장소를 작성 :

public abstract class GenericRepository<T> : IGenericRepository<T> where T : IEntityBase 

이 방법은, 기존 코드를 많이 변경하지 않고도 목표를 달성 할 수 있습니다.

해결 방법 2 :

또 다른 더러운 솔루션은 실제 인스턴스에 Record<T> 캐스팅하는 것입니다.

public void Delete(T entity) 
{ 
    if(typeof(T) == typeof(Document)) 
     Document myEntity = (Document)entity; 
    myEntity.Delete(); 
} 

각 방법으로 주조하는 것은 확실히 나쁜 생각입니다. 코드에서 좀 더 중앙 집중화 된 위치를 찾으십시오. 나는 너에게 그 길을 보여주고 싶었다.

해결 방법 3 :

다른 생각은 Record<T>에서 Delete 방법 A virtual 방법을 확인하는 것입니다. 하지만 ORM이 어떻게 작동하는지 또는 ORM에서 허용하는지 여부는 확실하지 않으므로 여기에 대해서는 언급하지 않겠습니다.