從dapper結果中調用每條記錄上的函數

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...我明白這是因為它不存在。我在這裡問什麼是最好的方法來完成我想要做的事情?是否有可能與短小精悍。

一般承認的答案

我擔心簡短的回答是你不能這樣做。

稍微長一點的答案是,在您的分頁查詢中,它本質上第二次傳遞數據,因為Dapper做了一些工作將每行的數據轉換為“T”的實例,然後它單獨調用“map”方法您用來調用“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;
}

如果你擔心的是你可能在非分頁查詢中加載了很多很多記錄,那麼值得記住的是, 所有這些記錄都將立即加載到內存中;它們不會一次一個地從數據庫中提取,因為您對返回的結果進行了枚舉,這可能會耗費相當多的資源(如果您要討論的數據很多,那麼您希望避免第二次枚舉) 。

這必須是這種情況,因為SQL連接在GetNonPagedQuery返回時關閉,因此無法通過調用者“按需”讀取數據。如果您真的在處理大量數據,那麼非分頁查詢可能不是最好的方法嗎?

請注意,在上面的代碼中,只有在枚舉行時才會調用“customAction”,在GetNonPagedQuery返回之前不會觸發這些行。如果“customAction”可能是一項昂貴的操作,那麼這可能對您有利。另一方面,如果你想在GetNonPagedQuery返回之前為每個結果調用“customAction”,那麼在Cast <dynamic>()之後你需要再多一次ToList()調用,它只取決於哪個場景對你更有用。


熱門答案

是的,它可能是:

請參閱有關每行類型切換的Dapper文檔部分。我懷疑(即我自己沒有嘗試過)如果你使用相同的系統將結果按照你想要的格式按下來閱讀每一行並明確地處理它,它就行不通。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow