将IReliableDictionary转换为IList

问题描述 投票:1回答:3

我有一个IReliableDictionary,需要将字典中的项目带入IList以从我可靠的服务中返回。

似乎我无法执行任何类型的.ToList,所以我确定我正在错误地处理它。

public async Task<IList<CustomerOrderItem>> GetOrdersAsync()
{   


   IReliableDictionary<CustomerOrderItemId, CustomerOrderItem> orderItems =
   await this.StateManager.GetOrAddAsync<IReliableDictionary<CustomerOrderItemId, CustomerOrderItem>>(CustomerOrderItemDictionaryName);

   Dictionary<KeyValuePair<CustomerOrderItemId, CustomerOrderItem>, KeyValuePair<CustomerOrderItemId, CustomerOrderItem>> items = orderItems.ToDictionary(v => v);

   IList<CustomerOrderItem> list = orderItems.ToList(); ???

   ...
}

关于如何从字典中取出项目并将其放入列表的任何想法?

azure-service-fabric
3个回答
0
投票

[IReliableDictionary<K,V>实现IEnumerable<KeyValuePair<K, V>>,因此您可以执行ToList

也许确保名称空间已导入。


0
投票

IReliableDictionary(就像IDictionary一样)是键值对的IEnumerable,所以您可以这样:

public async Task<IList<CustomerOrderItem>> GetOrdersAsync()
    {
        IReliableDictionary<CustomerOrderItemId, CustomerOrderItem> orderItems =
        await this.StateManager.GetOrAddAsync<IReliableDictionary<CustomerOrderItemId, CustomerOrderItem>>(CustomerOrderItemDictionaryName);

        var list = orderItems.Select(kvp => kvp.Value).ToList();
        return list;
    }

0
投票

在编写此答案时,IAsyncEnumerable是dotnet库的一部分,并且C#8.0添加了语法糖来支持它。

问题是ServiceFabric使用其自己的IAsyncEnumerable定义,因此您不能对其应用dotnet扩展方法和C#助手。

我想出的一种解决方案是使用一个简单的包装器将ServiceFabric的IAsyncEnumerable转换为本地的:

using System.Threading;
using System.Threading.Tasks;

using Generic = System.Collections.Generic;
using Fabric = Microsoft.ServiceFabric.Data;

public static class FabricAsyncEnumerableExtensions
{
    /// <summary>
    /// Converts ServiceFabric <see cref="Microsoft.ServiceFabric.Data.IAsyncEnumerable"/> to dotnet native <see cref="System.Collections.Generic.IAsyncEnumerable"/>.
    /// </summary>
    public static Generic.IAsyncEnumerable<T> ToGeneric<T>(this Fabric.IAsyncEnumerable<T> source) =>
        new AsyncEnumerableWrapper<T>(source);

    private class AsyncEnumerableWrapper<T> : Generic.IAsyncEnumerable<T>
    {
        private readonly Fabric.IAsyncEnumerable<T> _source;

        public AsyncEnumerableWrapper(Fabric.IAsyncEnumerable<T> source) => _source = source;

        public Generic.IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken _ = default)
        {
            Fabric.IAsyncEnumerator<T> enumerator = _source.GetAsyncEnumerator();
            return new AsyncEnumeratorWrapper<T>(enumerator);
        }
    }

    private class AsyncEnumeratorWrapper<T> : Generic.IAsyncEnumerator<T>
    {
        private readonly Fabric.IAsyncEnumerator<T> _source;

        public AsyncEnumeratorWrapper(Fabric.IAsyncEnumerator<T> source) => _source = source;

        public async ValueTask DisposeAsync() =>
            await Task.Run(_source.Dispose).ConfigureAwait(false);

        public async ValueTask<bool> MoveNextAsync() =>
            await _source.MoveNextAsync(default).ConfigureAwait(false);

        public T Current => _source.Current;
    }
}

使用它就像调用扩展方法一样简单,然后将其用作常规的IAsyncEnumerable

Fabric.IAsyncEnumerable<KeyValuePair<Guid, Product>> asyncProducts = GetAsyncProducts();
return await asyncProducts.ToGeneric()
    .Select(p => p.Value)
    .ToListAsync()
    .ConfigureAwait(false);
© www.soinside.com 2019 - 2024. All rights reserved.