使用IQueryable查询方法时返回IEnumerable

本文关键字:返回 IEnumerable 方法 IQueryable 查询 使用 | 更新日期: 2023-09-27 17:57:40

如果您有一个返回IEnumerable但内部返回IQueryable的方法,即使IQueryable推迟执行,返回IEnumerable是否会强制执行?

public IEnumerable<Customer> Customers()
{
    IEnumerable<Customer> customers = null;
try
{
    customers = from c in GetCustomers // IQueryable
            where c.Name=="JO"
            select c;
    }
    catch (SqlException ex)
    {
    }
    return customers;
}

使用IQueryable查询方法时返回IEnumerable

您返回的结果将是可枚举的,并将推迟执行,直到您开始枚举它。但是,与IQueryable不同,它不会被任何进一步的操作所更改。

例如,如果您之后执行了类似.Sum()的操作,它将在本地计算机上执行,而IQueryable可能会将Sum()发送到远程数据库或web服务。

首先,IQueryable<T>实现了IEnumerable<T>,所以您在这里并没有真正"强制"任何东西,因为IQueryable<T>只会被返回,不需要求值。

其次,IEnumerable<T>通常也被延迟评估(通过.ToArray().ToList()foreach()等)

由于IQueryable实现了IEnumerable,所以在返回对象时不会强制执行任何操作。

只有执行以下操作之一(但不限于),才能强制执行:

  • ToList()
  • FirstOrDefault()

在实际需要集合之前,不会执行代码;例如作为DataSource。

您不会强制执行,因为IQueryableIEnumerable都是延迟求值的,而IQueryable实现了IEnumerable,因此不需要进行任何转换。

如果您的体系结构没有针对这种情况进行很好的调整,这实际上会带来一个问题——返回的IQueryable只在评估结果后(即迭代结果时)执行查询。如果此时数据库连接已关闭,则会出现异常。

相关文章: