IReliableDictionary 上的 Linq 查询
Linq query on IReliableDictionary
我查看和修改了很多代码,但还没有找到针对 IReliableDictionary
执行 Linq 查询的方法。我知道它与标准 IDictionary
不同,但我很好奇是否有人运气好。不幸的是,我开始认为这是不可能的。
如果您需要处理比简单 GetByKey()
更复杂的操作,您需要通过 IReliableDictionary.CreateEnumerable()
method, which you would then be able to query similar to the following example from the comments in this discussion 显式创建它的本地集合:
IAsyncEnumerable<KeyValuePair<int, string="">> enumerable = await myDictionary.CreateEnumerableAsync(tx);
using (IAsyncEnumerator<KeyValuePair<int, string="">> e = enumerable.GetAsyncEnumerator())
{
while (await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
{
doSomething(e.Current);
}
}
这可能根本不适合您的情况,但它似乎是执行任何类型 "advanced queries" 的唯一方法。
目前,没有在可靠字典上执行 linq 查询的正常方法。话虽如此,您可以做一些事情。如前所述,CreateEnumerableAsync 方法存在的原因是因为服务结构将可靠字典分页到磁盘,但如果您知道底层集合很小并且您可以承受性能损失,那么以下 class 将起作用.
public static class AsyncEnumerableExtensions
{
/// <summary>
/// Converts the collection to a list
/// </summary>
/// <typeparam name="TValType">value type of the collection</typeparam>
/// <param name="enumerator">enumerator to convert</param>
/// <param name="ct">cancellation token for the async operations</param>
/// <param name="tx">tx to enforce that this is called in a transactional context</param>
/// <returns>a list containing all elements in the origin collection</returns>
public static async Task<IList<TValType>> ToListAsync<TValType>(
this IAsyncEnumerator<TValType> enumerator,CancellationToken ct, ITransaction tx)
{
IList<TValType> ret = new List<TValType>();
while (await enumerator.MoveNextAsync(ct).ConfigureAwait(false))
{
ret.Add(enumerator.Current);
}
return ret;
}
/// <summary>
/// Converts the collection to a list
/// </summary>
/// <typeparam name="TValType">value type of the collection</typeparam>
/// <param name="enumerator">enumerator to convert</param>
/// <param name="tx">tx to enforce that this is called in a transactional context</param>
/// <returns>a list containing all elements in the origin collection</returns>
public static Task<IList<TValType>> ToListAsync<TValType>(
this IAsyncEnumerator<TValType> enumerator, ITransaction tx)
{
return enumerator.ToListAsync(CancellationToken.None,tx);
}
/// <summary>
/// Converts the collection to a list
/// </summary>
/// <typeparam name="TValType">value type of the collection</typeparam>
/// <param name="enumerable">enumerator to convert</param>
/// <param name="ct">cancellation token for the async operations</param>
/// <param name="tx">tx to enforce that this is called in a transactional context</param>
/// <returns>a list containing all elements in the origin collection</returns>
public static Task<IList<TValType>> ToListAsync<TValType>(this IAsyncEnumerable<TValType> enumerable,
CancellationToken ct, ITransaction tx)
{
return enumerable.GetAsyncEnumerator().ToListAsync(ct,tx);
}
/// <summary>
/// Converts the collection to a list
/// </summary>
/// <typeparam name="TValType">value type of the collection</typeparam>
/// <param name="enumerable">enumerator to convert</param>
/// <param name="tx">tx to enforce that this is called in a transactional context</param>
/// <returns>a list containing all elements in the origin collection</returns>
public static Task<IList<TValType>> ToListAsync<TValType>(this IAsyncEnumerable<TValType> enumerable, ITransaction tx)
{
return enumerable.GetAsyncEnumerator().ToListAsync(tx);
}
}
您还可以实现自己的自定义枚举器和扩展方法,以高效方式对数据执行类似于 linq 查询的操作。我写了一些我想发布的,但他们首先需要一些润色。我有一种潜移默化的感觉,服务结构团队可能已经在处理它,但如果发生这种情况或何时发生,你的猜测和我的一样好。
正确的 LINQ 不能与 IAsyncEnumerator 一起工作
var wgEnumerable = await voteDictionary.CreateEnumerableAsync(tx);
using(IAsyncEnumerator<KeyValuePair<string, int>> enumerator = wgEnumerable.GetAsyncEnumerator())
{
while(await enumerator.MoveNextAsync(CancellationToken.None))
{
//Do something
}
}
看起来 MS 在最新的 SF 版本中删除了执行 linq 查询的功能。
将 SerivceFabric IAsyncEnumerable
转换为 dotnet 后,可以使用 Async Linq。
请参考这个回答:
Convert IReliableDictionary to IList
我查看和修改了很多代码,但还没有找到针对 IReliableDictionary
执行 Linq 查询的方法。我知道它与标准 IDictionary
不同,但我很好奇是否有人运气好。不幸的是,我开始认为这是不可能的。
如果您需要处理比简单 GetByKey()
更复杂的操作,您需要通过 IReliableDictionary.CreateEnumerable()
method, which you would then be able to query similar to the following example from the comments in this discussion 显式创建它的本地集合:
IAsyncEnumerable<KeyValuePair<int, string="">> enumerable = await myDictionary.CreateEnumerableAsync(tx);
using (IAsyncEnumerator<KeyValuePair<int, string="">> e = enumerable.GetAsyncEnumerator())
{
while (await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
{
doSomething(e.Current);
}
}
这可能根本不适合您的情况,但它似乎是执行任何类型 "advanced queries" 的唯一方法。
目前,没有在可靠字典上执行 linq 查询的正常方法。话虽如此,您可以做一些事情。如前所述,CreateEnumerableAsync 方法存在的原因是因为服务结构将可靠字典分页到磁盘,但如果您知道底层集合很小并且您可以承受性能损失,那么以下 class 将起作用.
public static class AsyncEnumerableExtensions
{
/// <summary>
/// Converts the collection to a list
/// </summary>
/// <typeparam name="TValType">value type of the collection</typeparam>
/// <param name="enumerator">enumerator to convert</param>
/// <param name="ct">cancellation token for the async operations</param>
/// <param name="tx">tx to enforce that this is called in a transactional context</param>
/// <returns>a list containing all elements in the origin collection</returns>
public static async Task<IList<TValType>> ToListAsync<TValType>(
this IAsyncEnumerator<TValType> enumerator,CancellationToken ct, ITransaction tx)
{
IList<TValType> ret = new List<TValType>();
while (await enumerator.MoveNextAsync(ct).ConfigureAwait(false))
{
ret.Add(enumerator.Current);
}
return ret;
}
/// <summary>
/// Converts the collection to a list
/// </summary>
/// <typeparam name="TValType">value type of the collection</typeparam>
/// <param name="enumerator">enumerator to convert</param>
/// <param name="tx">tx to enforce that this is called in a transactional context</param>
/// <returns>a list containing all elements in the origin collection</returns>
public static Task<IList<TValType>> ToListAsync<TValType>(
this IAsyncEnumerator<TValType> enumerator, ITransaction tx)
{
return enumerator.ToListAsync(CancellationToken.None,tx);
}
/// <summary>
/// Converts the collection to a list
/// </summary>
/// <typeparam name="TValType">value type of the collection</typeparam>
/// <param name="enumerable">enumerator to convert</param>
/// <param name="ct">cancellation token for the async operations</param>
/// <param name="tx">tx to enforce that this is called in a transactional context</param>
/// <returns>a list containing all elements in the origin collection</returns>
public static Task<IList<TValType>> ToListAsync<TValType>(this IAsyncEnumerable<TValType> enumerable,
CancellationToken ct, ITransaction tx)
{
return enumerable.GetAsyncEnumerator().ToListAsync(ct,tx);
}
/// <summary>
/// Converts the collection to a list
/// </summary>
/// <typeparam name="TValType">value type of the collection</typeparam>
/// <param name="enumerable">enumerator to convert</param>
/// <param name="tx">tx to enforce that this is called in a transactional context</param>
/// <returns>a list containing all elements in the origin collection</returns>
public static Task<IList<TValType>> ToListAsync<TValType>(this IAsyncEnumerable<TValType> enumerable, ITransaction tx)
{
return enumerable.GetAsyncEnumerator().ToListAsync(tx);
}
}
您还可以实现自己的自定义枚举器和扩展方法,以高效方式对数据执行类似于 linq 查询的操作。我写了一些我想发布的,但他们首先需要一些润色。我有一种潜移默化的感觉,服务结构团队可能已经在处理它,但如果发生这种情况或何时发生,你的猜测和我的一样好。
正确的 LINQ 不能与 IAsyncEnumerator 一起工作
var wgEnumerable = await voteDictionary.CreateEnumerableAsync(tx);
using(IAsyncEnumerator<KeyValuePair<string, int>> enumerator = wgEnumerable.GetAsyncEnumerator())
{
while(await enumerator.MoveNextAsync(CancellationToken.None))
{
//Do something
}
}
看起来 MS 在最新的 SF 版本中删除了执行 linq 查询的功能。
将 SerivceFabric IAsyncEnumerable
转换为 dotnet 后,可以使用 Async Linq。
请参考这个回答: Convert IReliableDictionary to IList