wake-up-neo.com

Ausführen einer asynchronen Azure-Tabellenspeicherabfrage Client-Version 4.0.1

Abfragen ausführen möchten Async auf Azure Storage Client Version 4.0.1

Es gibt KEINE Methode ExecuteQueryAsync ().

Ich vermisse etwas? Sollen wir ExecuteQuerySegmentedAsync weiterhin verwenden? Vielen Dank.

56
Jose Ch.

Am Ende mache ich eine Erweiterungsmethode, um ExecuteQuerySegmentedAsync zu verwenden. Ich bin mir nicht sicher, ob diese Lösung optimal ist. Wenn jemand einen Kommentar hat, zögern Sie bitte nicht.

public static async Task<IList<T>> ExecuteQueryAsync<T>(this CloudTable table, TableQuery<T> query, CancellationToken ct = default(CancellationToken), Action<IList<T>> onProgress = null) where T : ITableEntity, new()
    {

        var items = new List<T>();
        TableContinuationToken token = null;

        do
        {

            TableQuerySegment<T> seg = await table.ExecuteQuerySegmentedAsync<T>(query, token);
            token = seg.ContinuationToken;
            items.AddRange(seg);
            if (onProgress != null) onProgress(items);

        } while (token != null && !ct.IsCancellationRequested);

        return items;
    }
74
Jose Ch.

Wenn die Tabellenabfrage eine take-Klausel enthält, gibt die angegebene Lösung mehr Elemente zurück, als von der Abfrage angefordert wurden. Eine kleine Änderung des while-Ausdrucks löst dieses Problem.

public static async Task<IList<T>> ExecuteQueryAsync<T>(this CloudTable table, TableQuery<T> query, CancellationToken ct = default(CancellationToken), Action<IList<T>> onProgress = null) where T : ITableEntity, new()
{
    var runningQuery = new TableQuery<T>()
    {
        FilterString = query.FilterString,
        SelectColumns = query.SelectColumns
    };

    var items = new List<T>();
    TableContinuationToken token = null;

    do
    {
        runningQuery.TakeCount = query.TakeCount - items.Count;

        TableQuerySegment<T> seg = await table.ExecuteQuerySegmentedAsync<T>(runningQuery, token);
        token = seg.ContinuationToken;
        items.AddRange(seg);
        if (onProgress != null) onProgress(items);

    } while (token != null && !ct.IsCancellationRequested && (query.TakeCount == null || items.Count < query.TakeCount.Value));

    return items;
}

GEÄNDERT : Dank eines Vorschlags von PaulG wurde das Problem mit der Ergebniszählung behoben, wenn die Abfrage eine take-Klausel enthält und ExecuteQuerySegmentedAsync Elemente in mehreren Durchgängen zurückgibt.

14
Davor

Dies ist zusätzlich zu @JoseCh. 's Antwort.

Hier ist eine Erweiterungsmethode, mit der Sie einen EntityResolver angeben können:

public static async Task<IList<TResult>> ExecuteQueryAsync<T, TResult>(this CloudTable table, TableQuery query, EntityResolver<TResult> resolver, Action<IList<TResult>> onProgress = null, CancellationToken cancelToken = default(CancellationToken))
            where T : ITableEntity, new()
{
    var items = new List<TResult>();
    TableContinuationToken token = null;

    do
    {
        TableQuerySegment<TResult> seg = await table.ExecuteQuerySegmentedAsync(query: query, resolver: resolver, token: new TableContinuationToken(), cancellationToken: cancelToken).ConfigureAwait(false);
        token = seg.ContinuationToken;
        items.AddRange(seg);
        onProgress?.Invoke(items);
     }
     while (token != null && !cancelToken.IsCancellationRequested);
         return items;
     }
}

Es kann verwendet werden, wenn Sie nur die Ergebnismenge einer einzelnen Spalte im Speicher zurückgeben möchten:

// maps to a column name in storage
string propertyName = nameof(example.Category);

// Define the query, and select only the Category property.
var projectionQuery = new TableQuery().Select(new string[] { propertyName });

// Define an entity resolver to work with the entity after retrieval.
EntityResolver<string> resolver = (pk, rk, ts, props, etag) => props.ContainsKey(propertyName) ? props[propertyName].StringValue : null;

var categories = (await someTable.ExecuteQueryAsync<DynamicTableEntity, string>(query: projectionQuery, resolver: resolver).ConfigureAwait(false)).ToList()
0
Zze