如何:使用异步方法与LINQ自定义扩展方法

问题描述:

我有一个LINQ自定义扩展方法:如何:使用异步方法与LINQ自定义扩展方法

public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> items, Func<T, TKey> property) 
{ 
    return items.GroupBy(property).Select(x => x.First()); 
} 

,我使用它是这样的:

var spc = context.pcs.DistinctBy(w => w.province).Select(w => new 
      { 
       abc = w 
      }).ToList(); 

但问题是我不'不想ToList()我想要这样的东西

var spc = await context.pcs.DistinctBy(w => w.province).Select(w => new 
      { 
       abc = w 
      }).ToListAsync(); 

With Async。但没有找到异步。如何使我的自定义方法distinctBy这样我也可以异步使用它?

+0

你是否已经尝试过使用'IQueryable'而不是'IEnumerable'两个返回类型和参数的数据项? 看起来像'ToListAsync'是EF上'IQueryable'的扩展方法:https://msdn.microsoft.com/en-us/library/dn220262%28v=vs.113%29.aspx?f=255&MSPPError= -2147217396 – Hypnobrew

ToListAsync()扩展方法扩展了IQueryable<T>,但是您的DistinctBy()方法正在扩展(并返回)IEnumerable<T>

显然,ToListAsync()不适用于IEnumerable<T>,因为它使用Linq-To-Objects(内存中)并且不能潜在阻塞(不涉及I/O)。

试试这个:

public static IQueryable<T> DistinctBy<T, TKey>(this IQueryable<T> items, Expression<Func<T, TKey>> property) 
{ 
    return items.GroupBy(property).Select(x => x.First()); 
} 

请注意,我也改变了property参数从Func<>Expression<Func<>>为了匹配Queryable.GroupBy(避免Enumerable.GroupBy)。

MSDN

+1

作为补充澄清,最好尽可能使用'IQueryable'而不是'IEnumerable'来避免进行多个数据库查询。 :) – Hypnobrew

+0

@Hypnobrew,这并非总是如此。通常,您需要事先显式提取您知道的所有数据,然后将其作为“IEnumerable '返回。总是返回'IQueryable '很容易出错,有时被认为是漏洞抽象。 – haim770

+1

是的,你是对的。如果让你的'IQueryable'在类之间流动,甚至在层之间流动,那么可能会有泄漏的抽象。在上面的例子中,它看起来像一个独立的地方,IQuerable是合适的,您希望尽可能延迟查询。 – Hypnobrew