2016-12-27 85 views
11

我有一個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

回答

17

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