2017-01-04 6 views
0

나는 교류 #의 noobie,하지만 여기에 내가 뭘하려고 오전의 요지입니다 :C 샤프 일반 단정 한 쿼리 두 테이블

public IEnumerable<T> GetAll<T, K>(string schemaName) where T : GenericModel 
    { 
     var sql = @"SELECT * from " + 
      schemaName + "." + T.getTableName() + " primaryTable LEFT JOIN " + 
      schemaName + "." + K.getTableName() + 
      " ForeignTable on ForeignTable.id = primaryTable." + T.getForeignFieldName(); 

     return _connection.Query<T, K, T>(sql, (primary, foreign) => 
     { (primary = T.getForeignFieldName()) = foreign; return primary; }); 
    } 

를 예를 들어 T = 직원 및 K = 사람

으로는
public IEnumerable<Employee> GetAll(string schemaName) 
    { 
     var sql = @"SELECT * from " + schemaName + 
      ".Employee primaryTable LEFT JOIN " + 
      schemaName + ".Person ForeignTable "+ 
      "on ForeignTable.id = primaryTable.person_id"; 
     return _connection.Query<EmployeeModel, PersonModel, EmployeeModel> 
      (sql, (primary, foreign) => { primary.person = foreign; return primary; }); 
    } 

GenericModel 파생 클래스 (EmployeePerson) 미행되는 getForeignFieldName()getTableName() 갖는다

T

Person { 
    int id; 
    string Name; 
    string address; 
    int age; 
} 

Employee { 
    int id; 
    int person_id; 
    Person person; 
    double salary; 

}

는 물론 일반 솔루션이 작동하지 않습니다 내가 SQL 주입 알고 있어요 :처럼 그는 예를 들어 모델 보일 수 있습니다. Dapper의 Query() 함수로 설명한 방식을 사용할 수있는 일반적인 메서드가 필요합니다. 쿼리의 생성 :-) 예약을 꾸는 한 - Dapper's Multi Mapping

+0

왜이 작업을 수행하려고합니까? 대신보기/저장 프로 시저 사용을 고려하십시오. – Milney

+0

@Milney 두 개의 오버로드를 고려하십시오. 하나는 Employee 데이터를 반환하고 다른 하나는 Null 인 것으로, 다른 하나는 Employee가 쿼리 될 때 Person 데이터를 반환합니다. 이제 그것을 일반화해라. 그것은 너무 많은 뷰 (비슷한 테이블을 가진 많은 테이블)이다. 반면 쿼리를 사용하면 Person 데이터가 필요할 때마다 과부하를 호출 할 수 있습니다. – Achilles

답변

0

그래, 미안하지만, 가장 친절한 방법 :이 작업을 수행 할 수있는 일반적인 함수를 작성 어떻게 즉

, 이고 원하는 데이터가 무엇이며 반환 된 개체가 지정되는 순간입니다. 사람들은 동적으로 생성 된 SQL을 사용하여 WHERE 또는 ORDER BY 절을 사용하지만 이미 내 견해에서 완전히 반 패턴입니다. 어떤 테이블에 대한 최종 결정을 연기함으로써, 가치가없는 클래스를 얻게됩니다. 더 나쁜 것은 WHERE 절과 같은 중요한 가능성을 차단하거나 반환되는 열을 제한하는 것입니다. 예의 바른 사회에서 두 개의 조인 된 테이블에서 모든 행의 모든 ​​열을 요청하는 것이 다소 편한 것으로 간주됩니다!

이야기의 도덕, 모든 것을 할 수있는 1 개의 쿼리를 작성하지 마십시오. 필요할 때 바로 필요한 정보를 제공하는 더 작은 쿼리를 작성하십시오.

+0

당신의 요점을 봅니다. 생성 된 POCOS에 모든 열을 반환하는 "GetAll()"메서드가 포함되기를 원하는 사람을 돕고있었습니다. 그게 쉬운 일이긴하지만, 나는 그것이 너무 반복적이어서 질문이라고 생각합니다. – Achilles

+0

문제 없습니다. POCO 생성에 대해 전혀 이해하지 못했습니다. 누가 또는 무엇을 POCOs를 생성하고 있습니까? 원하는 경우 GetAll() 메서드는 일반적으로 POCO가 아니라 저장소에 있습니다. POCO의 개념은 [ "Persistence Ignorant"]입니다. (http://codeidol.com/community/dotnet/poco-as-a-lifestyle/9476/) – bbsimonbb

+0

유용한 T4 스크립트는 db 정보 스키마. 각각의 생성 된 POCO에 나중에 생성 할 때 생성시 GetAll()을 포함하는 것이 더 쉽습니다. 나는 POCO에 데이터베이스 컬럼 이외의 다른 것을 포함하는 것에 엄격히 반대한다. 그러나 헤이! 인생은 거의 공평하지 않습니다. – Achilles