NET问答:如何理解 IEnumerable<T> 和 IQueryable<T>

咨询区

  • stackoverflowuser

请问类型 IQueryable<T>IEnumerable<T>  有什么异同?我应该使用哪一个而不是另一个,代码如下:


IQueryable<Customer> custs = from c in db.Customers
where c.City == "<City>"
select c;

IEnumerable<Customer> custs = from c in db.Customers
where c.City == "<City>"
select c;

我知道这两者都是延迟执行,我应该如何选择?

回答区

  • Kasper Roma

是的,两者都是延迟执行,我来用 SQL Server profiler 来演示两者的不同,考虑下面的代码:


MarketDevEntities db = new MarketDevEntities();

IEnumerable<WebLog> first = db.WebLogs;
var second = first.Where(c => c.DurationSeconds > 10);
var third = second.Where(c => c.WebLogID > 100);
var result = third.Where(c => c.EmailAddress.Length > 11);

Console.Write(result.First().UserName);

SQL Server profiler 中我捕获到了如下的sql。


"SELECT * FROM [dbo].[WebLog]"

这张表中大概有 100w 条记录,sql花费了大概 90s, 显而易见,代码首先会将 WebLog,也 就是将所有的表记录全部灌入到内存中,然后依次使用 Where() 在内存中进行过滤。

接下来用 IQueryable 替代 IEnumerable, 再次观察一下 SQL Server profiler,可以捕获如下sql。


"SELECT TOP 1 * FROM [dbo].[WebLog] WHERE [DurationSeconds] > 10 AND [WebLogID] > 100 AND LEN([EmailAddress]) > 11"

这个 sql 大概花费了 4s。

IQueryable 中有一个 Expression 属性,它存储着 表达式树,它的完整构建在于 result 变量处(这里是延迟执行),当真正执行的时候,这个 表达式树 会被解析成 sql 到数据库中执行。

点评区

Kasper Roma 大佬说的是有理有节,图文并茂,一看就懂,大写的????????,我还真的特意看了下有没有 Expression 属性 ????????????


    //
    // Summary:
    //     Provides functionality to evaluate queries against a specific data source wherein
    //     the type of the data is not specified.
    public interface IQueryable : IEnumerable
    {
        //
        // Summary:
        //     Gets the type of the element(s) that are returned when the expression tree associated
        //     with this instance of System.Linq.IQueryable is executed.
        //
        // Returns:
        //     A System.Type that represents the type of the element(s) that are returned when
        //     the expression tree associated with this object is executed.
        Type ElementType { get; }
        //
        // Summary:
        //     Gets the expression tree that is associated with the instance of System.Linq.IQueryable.
        //
        // Returns:
        //     The System.Linq.Expressions.Expression that is associated with this instance
        //     of System.Linq.IQueryable.
        Expression Expression { get; }
        //
        // Summary:
        //     Gets the query provider that is associated with this data source.
        //
        // Returns:
        //     The System.Linq.IQueryProvider that is associated with this data source.
        IQueryProvider Provider { get; }
    }

原文链接:https://stackoverflow.com/questions/2876616/returning-ienumerablet-vs-iqueryablet

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值