-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query: Implement ToLookupAsync #15916
Comments
We need a new |
We decided not to fix this since the implementation was converting queryable to enumerable and calling API on top of it (implementation was coming from IX-Async). Users should themselves convert the queryable to enumerable and call ToLookup API from appropriate library. |
Can ToLookup / ToLookupAsync be translated appropriately via |
For anyone in need of a internal static class QueryableExtensions
{
public static Task<ILookup<TKey, TSource>> ToLookupAsync<TSource, TKey>(
[NotNull] this IQueryable<TSource> source,
[NotNull] Func<TSource, TKey> keySelector,
CancellationToken cancellationToken = default)
where TKey : notnull
=> ToLookupAsync(source, keySelector, e => e, comparer: null, cancellationToken);
public static Task<ILookup<TKey, TSource>> ToLookupAsync<TSource, TKey>(
[NotNull] this IQueryable<TSource> source,
[NotNull] Func<TSource, TKey> keySelector,
[NotNull] IEqualityComparer<TKey> comparer,
CancellationToken cancellationToken = default)
=> ToLookupAsync(source, keySelector, e => e, comparer, cancellationToken);
public static Task<ILookup<TKey, TElement>> ToLookupAsync<TSource, TKey, TElement>(
[NotNull] this IQueryable<TSource> source,
[NotNull] Func<TSource, TKey> keySelector,
[NotNull] Func<TSource, TElement> elementSelector,
CancellationToken cancellationToken = default)
where TKey : notnull
=> ToLookupAsync(source, keySelector, elementSelector, comparer: null, cancellationToken);
public static async Task<ILookup<TKey, TElement>> ToLookupAsync<TSource, TKey, TElement>(
[NotNull] this IQueryable<TSource> source,
[NotNull] Func<TSource, TKey> keySelector,
[NotNull] Func<TSource, TElement> elementSelector,
IEqualityComparer<TKey> comparer,
CancellationToken cancellationToken = default)
where TKey : notnull
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector));
return (await source.ToListAsync(cancellationToken)).ToLookup(keySelector, elementSelector, comparer);
}
} |
I see this thread is abandoned, but I'll leave this here in case anyone stumbles upon it in the future. From @huysentruitw's example, I changed the implementation of the method that accepts an public static async Task<ILookup<TKey, TElement>> ToLookupAsync<TSource, TKey, TElement>(
this IQueryable<TSource> source,
Expression<Func<TSource, TKey>> keySelector,
Expression<Func<TSource, TElement>> elementSelector,
IEqualityComparer<TKey> comparer,
CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(source);
ArgumentNullException.ThrowIfNull(keySelector);
ArgumentNullException.ThrowIfNull(elementSelector);
var groupedElements = await source
.GroupBy(keySelector, elementSelector)
.ToArrayAsync(cancellationToken);
return groupedElements
.SelectMany(g => g
.Select(x => new
{
g.Key,
Element = x,
}))
.ToLookup(x => x.Key, x => x.Element, comparer);
} This is the simplest implementation I could come up with without a custom implementation of |
@Synthwaver the extension methods I've posted above can be applied after doing your own projection in a |
@huysentruitw yes, I understand. I'd just like to be able to use it something like this: var bookTitlesByReaderIds = await query.ToLookupAsync(x => x.ReaderId, x => x.Book.Title); Similar to how I often use UPD: |
Since Lookup class is semi-public & IX-Async's implementation was internal.
The text was updated successfully, but these errors were encountered: