【问题标题】:How to: Use async methods with LINQ custom extension method如何:将异步方法与 LINQ 自定义扩展方法一起使用
【发布时间】:2017-05-11 11:55:22
【问题描述】:

我有一个 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();

使用异步。但是没有找到异步。我怎样才能让我的自定义方法 distinctBy 这样我也可以异步使用它?

【问题讨论】:

  • 您是否尝试过使用IQueryable 而不是IEnumerable 作为返回类型和参数项?看起来ToListAsyncIQueryable EF 的扩展方法:msdn.microsoft.com/en-us/library/…

标签: c# .net entity-framework linq extension-methods


【解决方案1】:

ToListAsync() 扩展方法正在扩展 IQueryable&lt;T&gt;,但您的 DistinctBy() 方法正在扩展(并返回)IEnumerable&lt;T&gt;

很明显,ToListAsync() 不适用于IEnumerable&lt;T&gt;,因为它使用 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&lt;&gt; 更改为Expression&lt;Func&lt;&gt;&gt; 以匹配Queryable.GroupBy(并避免Enumerable.GroupBy)。

MSDN

【讨论】:

  • 作为补充说明,最佳实践是尽可能使用IQueryable 而不是IEnumerable,以避免进行多个数据库查询。 :)
  • @Hypnobrew,这并不总是正确的。通常你会想要事先明确地获取你知道你需要的所有数据,然后将其返回为IEnumerable&lt;T&gt;。总是返回 IQueryable&lt;T&gt; 容易出错,有时被认为是泄漏抽象。
  • 是的,你是对的。如果您让IQueryable 在类之间流动,甚至更糟糕的是,在层之间流动,则可能存在抽象泄漏。在上面的示例中,它看起来像一个孤立的地方,适合使用 IQuerable,您希望尽可能地推迟查询。
猜你喜欢
  • 2014-02-05
  • 1970-01-01
  • 1970-01-01
  • 2011-01-07
  • 2012-09-09
  • 1970-01-01
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
相关资源
最近更新 更多