큰 결과에서 각 레코드의 함수 호출

asp.net-mvc-5 c# dapper

문제

일부 필드 값을 설정하는 각 레코드에서 함수를 호출하려고합니다. 결과가 페이징 될 예정인 경우 다음과 같은 방식으로 결과가 나타납니다.

public IDataWrapper GetPagedQuery<T>(string myQuery, object param, Action<T> customAction)
{
    var obj = new DataWrapper ();
    using (var oConn = CreateConnection(ConnectionString))
    {
        TotalPages totalRows = null;
        var list = oConn.Query<T, TotalPages, T>(myQuery, (e, t) =>
        {
            totalRows = t;
            if (mapAction != null) customAction(e);
            return e;
        }, param, splitOn: "SplitOn");
        obj.RowsFound = (IEnumerable<dynamic>)list;
        obj.TotalRows = totalRows == null ? 0 : totalRows.TotalRows;
    }
    return obj;
}

내 문제는 결과가 호출 될 의도가없는 경우에 발생합니다. 첫 번째 예제에서 내 쿼리는 열에 분할을 포함하고 이것이 모든 작동하지만 내 다음 쿼리는 Select Column1, Column2 FROM MyAwesomeTable 과 같은 간단한 쿼리로 모든 행, 열 등을 반환합니다.

문제는 다시 돌아 오는 각 결과에 customAction을 적용해야한다는 것입니다. 이제는 몇 백만 건의 레코드가 다시 올 가능성이 있다는 것을 상상해보십시오. (제 상황을 생각하면 비현실적이지 않습니다.) 저는 각 레코드를 다시 반복하고 내 방법을 적용하기를 원하지 않기 때문에 그 방법을 원합니다. 데퍼가 첫 번째 경우와 마찬가지로 결과를 반환 할 때 적용됩니다.

여기 내가 시도한 것이있다.

public IDataWrapper GetNonPagedQuery<T>(string myQuery, object param, Action<T> customAction)
{
    var obj = new DataWrapper ();
    using (var oConn = CreateConnection(ConnectionString))
    {
        var list = oConn.Query<T>(myQuery, (e) =>
        {
            if (mapAction != null) customAction(e);
            return e;
        }, param).ToList();
        obj.RowsFound = (IEnumerable<dynamic>)list;
        obj.TotalRows = list.Count();
    }
    return obj;
}

위의 코드에서 메서드 Query<T>(etc... 해결할 수 없다는 오류가 발생합니다. Query<T>(etc... 존재하지 않기 때문에 이해합니다. 지금 내가하려고하는 것을 성취하는 가장 좋은 방법이 무엇인지 묻습니다. ? 그것은 대담한 사람과 함께 가능합니까?

수락 된 답변

나는 짧은 대답은 당신이 이것을 할 수 없다는 것입니다.

약간 긴 대답은 말끔는 "T"의 인스턴스로 각 행의 데이터를 변환하는 몇 가지 작업을 수행하고 다음은 "지도"방법에 별도의 호출을 이후 페이징 쿼리에서, 그것은 본질적으로 데이터를 통해 두 번째 패스는 점이다 "customAction"에 전화하는 데 사용하는

따라서 단순한 페이징되지 않은 "conn.Query"호출 다음에 customAction을 실행하기위한 후속 전달이있는 것과 그 사이에는 거의 차이가 없습니다. 다음과 같은 것 :

public IDataWrapper GetNonPagedQuery<T>(string myQuery, object param, Action<T> customAction)
{
    var obj = new DataWrapper();
    using (var oConn = CreateConnection(ConnectionString))
    {
        var results = oConn
            .Query<T>(myQuery)
            .ToList();
        obj.TotalRows = results.Count();
        obj.RowsFound = results
            .Select(value =>
            {
                customAction(value);
                return value;
            })
            .Cast<dynamic>();
    }
    return obj;
}

걱정하지 않으면 페이징되지 않은 쿼리에서 많은 레코드를로드 할 수 있습니다. 모든 레코드가 메모리에 한 번에로드됩니다. 반환 된 결과를 열거 할 때 데이터베이스에서 하나씩 꺼내지지 않으며 리소스에 상당한 손실이 발생할 수 있습니다 (두 번째 열거 형을 피하기 위해 너무 많은 데이터를 사용하는 경우) .

GetNonPagedQuery가 반환 될 때 SQL 연결이 닫히고 호출자가 "요청시"데이터를 읽을 수 있도록 열어 둘 수있는 방법이 없기 때문에이 경우가되어야합니다. 방대한 양의 데이터로 작업하는 경우 비 페이징 쿼리가 최선의 방법이 아닐 수 있습니다.

위 코드에서 "customAction"은 행을 열거 할 때만 호출되며 GetNonPagedQuery가 반환되기 전에는 모두 실행되지는 않습니다. "customAction"이 잠재적으로 비싼 작업이라면 이점이 도움이 될 수 있습니다. 반면에 GetNonPagedQuery가 반환하기 전에 모든 결과에 대해 "customAction"을 호출하려면 Cast <dynamic> () 후에 ToList ()를 한 번 더 호출해야하며 어떤 시나리오가 더 유용할지에 따라 달라집니다.


인기 답변

예, 가능합니다 :

행 당 유형 전환 에 대한 Dapper 문서 섹션을 참조하십시오. 당신이 각 행을 읽고 명시 적으로 처리하여 원하는 형식으로 결과를 마사지하기 위해 동일한 시스템을 사용했다면 작동하지 않을 것이라고 나는 의심 스럽다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow