Dapper 강력 유형 컬렉션

c# dapper

문제

내 응용 프로그램에서는 Dapper를 사용하여 데이터베이스에 액세스합니다.

나는 다음 예제 코드를 가지고있다 :

public IEnumerable GetByParentId(Type childType, string table) 
{
    IDbConnection _connection = _dbProvider.GetConnection();

    var _sqlString = "select * from " + table;

    IEnumerable _ret = _connection.Query(_sqlString).ToList(); 
    //return IEnumerable<Dapper.SqlMapper.FastExpando> 

    return _ret;
}

FastExpando 항목을 내 childType 으로 캐스팅하거나 강력한 형식의 컬렉션을 반환하도록 Dapper를 강제 적용 할 수 있습니까?

메소드 서명을 변경할 수 없습니다!

수락 된 답변

리플렉션을 통해 Query 메소드를 호출하고 childType의 일반적인 TItem 인자를 제공 할 수 있습니다. 그런 다음 Dapper는 IEnumerable을 반환하고 캐스팅 할 수 있습니다. 또한, Dapper를 포크하여 (매우 크지는 않음) Query의 매우 간단한 오버로드를 만들 수 있습니다.이 유형은 (Type childType) 인수를 포함하고 적절한 메소드를 호출합니다.

당신이 직면 한 것은 C #이 제네릭을 사용하여 작업 할 때의 문제입니다. 정적으로 입력 된 언어이기 때문에 C #은 동적 유형에서 작동하지 않습니다. 동적으로 작업하고 싶다면 항상 리플렉션으로 끝납니다.

다음은 유형 인수로 query 메소드를 호출하는 방법의 샘플입니다. 이 문제를 조금 수정해야 할 수도 있습니다.

    public IEnumerable GetByParentId(Type childType, string table)
    {
        IDbConnection _connection = _dbProvider.GetConnection();

        var _sqlString = "select * from " + table;

        var t = typeof(SqlMapper);
        var genericQuery = t.GetMethods().Where(x => x.Name == "Query" && x.GetGenericArguments().Length == 1).First(); // You can cache this object.
        var concreteQuery = genericQuery.MakeGenericMethod(childType); // you can also keep a dictionary of these, for speed.
        var _ret = (IEnumerable)concreteQuery.Invoke(null, new object[] { _connection, _sqlString });

        return _ret;
    }

추가 :

또한 좀 더 일반적인 디자인 문제를 여기에서 볼 수 있습니다. 유형을 동적으로 지정하려고하지만 정적으로 유형이 지정된 오브젝트를 가져오고 자 할 수 있는지 (정적으로 가정하거나 반사를 계속하고 싶습니까?). 그렇다면 왜 ... 동적 인 인터페이스를 만드는 이유는 무엇입니까? 당신은 인터페이스를 변경할 수 없다고 말하지만, 이것은 약간 어리석은 것처럼 보입니다. 모든 컨텍스트는 정적으로 형식화 된 것으로 보이지만 어떤 이유로 인해 동적으로 형식화 된 메서드가 하나있는 것 같습니다. 컴파일 시간 동안 (또는 런타임의 일반적인 인수를 통해) 유형을 알고 있다면 메소드를 다음과 같이 변경하면됩니다.

    public IEnumerable<T> GetByParentId<T>(string table)
    {
        IDbConnection _connection = _dbProvider.GetConnection();
        var _sqlString = "select * from " + table;
        var _ret = _connection.Query<T>(_sqlString);
        return _ret;
    }


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