Rufen Sie eine Funktion für jeden Datensatz von dapper result auf

asp.net-mvc-5 c# dapper

Frage

Ich versuche, eine Funktion für jeden Datensatz aufzurufen, der einige Feldwerte festlegen wird. Wenn die Ergebnisse ausgelagert werden sollen, wird dies auf folgende Weise erreicht:

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;
}

Mein Problem tritt auf, wenn die Ergebnisse nicht ausgelagert werden sollen. Meine Abfrage im ersten Beispiel enthält Split für Spalte und das ist, warum alles funktioniert, jedoch ist meine nächste Abfrage eine einfache Abfrage, z. B. Select Column1, Column2 FROM MyAwesomeTable die alle Zeilen, Spalten usw. Select Column1, Column2 FROM MyAwesomeTable

Das Problem ist, dass ich customAction immer noch auf jedes Ergebnis anwenden muss, das zurückkommt. Stellen wir uns nun vor, dass es ein Potential von wenigen Millionen Datensätzen gibt (glauben Sie mir, das ist nicht unrealistisch angesichts meiner Situation), als solche möchte ich nicht jeden Datensatz neu durchlaufen und meine Methode anwenden, ich will diese Methode angewendet, wenn der Adrette Ergebnisse zurückgibt, genau wie im ersten Fall.

Hier ist was ich versucht habe:

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;
}

Ich bekomme einen Fehler für obigen Code, dass es die Methode Query<T>(etc... nicht lösen kann. Ich verstehe es, weil es nicht existiert. Ich frage mich, was der beste Weg wäre, um das zu erreichen, was ich versuche ? Ist das mit Dapper möglich?

Akzeptierte Antwort

Ich fürchte, dass die kurze Antwort ist, dass Sie das nicht tun können.

Die etwas längere Antwort ist, dass es sich bei Ihrer ausgelagerten Abfrage im Wesentlichen um einen zweiten Durchlauf der Daten handelt, da Dapper die Daten jeder Zeile in eine Instanz von "T" übersetzt und dann einen separaten Aufruf der "map" -Methode durchführt mit dem Sie Ihre "customAction" aufrufen.

Es würde also sehr wenig Unterschied zwischen diesem und einem einfachen nicht-paged "conn.Query" Aufruf geben, gefolgt von einem nachfolgenden Durchlauf, um Ihre customAction auszuführen. Etwas wie das Folgende:

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;
}

Wenn Sie befürchten, dass Sie viele, viele Datensätze in die nicht ausgelagerte Abfrage laden, sollten Sie bedenken, dass alle diese Datensätze gleichzeitig in den Speicher geladen werden. Sie werden nicht einzeln aus der Datenbank abgerufen, da Sie die zurückgegebenen Ergebnisse aufzählen. Dies könnte zu erheblichen Ressourcenverlusten führen (wenn Sie über so viele Daten sprechen, dass Sie eine zweite Aufzählung vermeiden wollten). .

Dies muss der Fall sein, da die SQL-Verbindung geschlossen wird, während GetNonPagedQuery zurückkehrt, und es daher nicht möglich ist, die Daten "auf Abruf" vom Aufrufer zu lesen. Wenn Sie wirklich mit großen Datenmengen arbeiten, ist vielleicht eine nicht ausgelagerte Abfrage nicht der beste Ansatz?

Beachten Sie, dass der "customAction" im obigen Code nur aufgerufen wird, wenn Sie über die Zeilen aufzählen, diese werden nicht alle ausgelöst, bevor GetNonPagedQuery zurückgibt. Wenn "customAction" möglicherweise eine teure Operation ist, kann dies für Sie von Vorteil sein. Wenn andererseits "customAction" für jedes Ergebnis aufgerufen werden soll, bevor GetNonPagedQuery zurückkehrt, benötigen Sie einen weiteren ToList () -Aufruf nach dem Cast <dynamic> (). Es kommt nur darauf an, welches Szenario für Sie nützlicher ist.


Beliebte Antwort

Ja, es ist möglicherweise:

Lesen Sie den Abschnitt der Dapper-Dokumente zum Typ Switching pro Zeile . Ich bezweifle (dh ich habe es nicht selbst ausprobiert), dass es nicht funktioniert, wenn Sie das gleiche System verwenden, um die Ergebnisse in das gewünschte Format zu bringen, indem Sie jede Zeile lesen und explizit verarbeiten.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow