Asp.net linq高性能解析

linq to EF

我们都知道asp.net经典的ef模型中linq的用法如下,但你们了解它高性能的远离吗?

  var temp = from u in dbcontext.DEPTs
                       where u.DEPTNO == 10
                       select u;

我们都知道上述代码实质上的返回值为 IQueryable<数据表类>,我们不妨看看IQueryable底层的定义

 		 Type ElementType { get; }
    
        Expression Expression { get; }   
        IQueryProvider Provider { get; }

可以看到这样的三行代码分别代表的意思是:

  • Type ElementType { get; }

顾名思义指定元素类型,这行代码即在我使用linq语句的时候指定了元素类型,如上方数据表类为DEPT,那么初始化的元素类型就为DEPT

  • Expression Expression { get; }
    Expression类型: 存储lambda表达式的表达式树,例:
Expression<Func<int, bool>> e = a => a > 0;

这里的Expression就指向了Func<int, bool>这个lambda表达式,存储结构如下:(上述from u in dbcontext.DEPTs
where u.DEPTNO == 10
select u表达式树结构差不多不多赘述)

在这里插入图片描述

  • IQueryProvider Provider { get; }
    当你需要返回数据的时候,Expression Provider指向指定类型的QueryProvider 就去解析表达式(Expression ), 解析后生成数据库脚本,去数据库取数据

了解完底层存储后,我们就可以阐述linq to EF(即上方linq的sql查询语句)的工作过程:

  1. linq表达式转换成Expression类型
  2. 给ElementType赋值,指定为DEPT类类型
  3. 将 EF Provider 赋值给Provider,用的时候,注意是用的时候,再去解析Expression,生成数据库脚本,从数据库拿指定条件的数据。

对比常规泛型集合(linq to object)的优势

1.效率
对比之下常规泛型集合,如:List ,Array等,使用方式如下,如果我们使用编译根据会发现,他们取数据的时候是先将数据从数据库中读到内存,即无视 where u.DEPTNO == 10这步,然后再从内存中过滤得到需要的数据,这种做法相比之下,效率显然不如前者

 var temp = from u in dbcontext.DEPTs.ToList()
                       where u.DEPTNO == 10
                       select u;

2.存储

我们也可以看看底层存储情况,如下图:

在这里插入图片描述可以看出linq to EF只存储定义,当需要数据时候执行初始化,生成provider,生成脚本取数据到内存这三步骤。而常规泛型集合则是直接加载到内存,若内存空间不够就两倍两倍的扩张,存储上显然也不如linq to EF

小结

所以,我们可以称List等常规集合称为本地集合 ,而IQueryable称为离线集合

发布了22 篇原创文章 · 获赞 0 · 访问量 584
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览