• Entity Framework基础-第三篇


    查询的两种过滤方法:

    1.linq to EF 数据库中过滤: 下图我们能看出来Linq表达式在执行的时候已经为我们生成高效的sql语句

    DemoTestEntities dbContext = new DemoTestEntities();
    var demoTest = from u in dbContext.UserInfo
                               where u.UserId>0 
                               select u;
     foreach (var item in demoTest)
     {
         Console.WriteLine(item.Age + "," + item.Name);
     }

    打开Sql Server Profiler ,看下到底生成了什么样的sql语句

    linq分析下Linq表达式的返回值:

    linq返回值用var来替换,其实它返回值是IQueryable<>类型,

    f12能看到它继承(暂这样理解)IEnumerable<T>,IQuery,IEnumerable。

    扩展下IQueryable<out T>中这个out起什么作用呢?我们就先简单的了解下"协变"和"逆变":

    协变out(安全):就是把一个子类的泛型集合赋值给父类的泛型集合,调用的时候用的是父类的泛型集合,一般用在方法的返回值,所以当集合中有out的时候可以用这个集合的父类来替换它接收数据。

    代码如下:

    //IQueryable可以用IEnumerable来替换或者替换成IQueryable<object>
    IQueryable<UserInfo> demoTest = from u in dbContext.UserInfo 
                               where u.UserId>0 
                               select u;
    //也可以把子类的泛型集合赋值给父类泛型集合
    IQueryable<object> objTest=demoTest;
    
    
    //也可以直接接收
    IEnumerable<UserInfo> demoTest = from u in dbContext.UserInfo 
                               where u.UserId>0 
                               select u;
    IQueryable<object> demoTest = from u in dbContext.UserInfo 
                               where u.UserId>0 
                               select u;

    逆变in(安全):把父类的泛型赋值给子类泛型集合,这有点难理解,为啥父类赋值给子类是安全的呢?

    原因是当子类赋值给父类时,父类还是调用自己的方法。逆变难点是"谁在用传过来的这个参数",下面的代码看似是把父类的泛型约束给子类,但是不用,真正调用的时候是在{}括号里面,关键再用的时候要保证安全

    Action<object> action  =  (a)  => { Console.WriteLine(a.GetType().Name); };
    Action<UserInfo> sunAction  = action;
    sunAction(new UserInfo());

    从上面介绍可以知道,所有的返回参数都是协变(也可以理解成外部调用),所有的传入参数都是逆变(也可以理解成内部调用)。在编译阶段会把代码补充完整,本质还是内部进行转换,只不过是编译不对其报错,其实就是语法糖。

    2.Linq to object内存过滤:把数据库中所有的数据都查询到程序中,在进行过滤(大数据时,不易用这种)

    DemoTestEntities dbContext = new DemoTestEntities();
                //把数据从UserInfo表中所有数据都取出来,转换成List集合,然后在遍历这集合过滤
                //list集合存放在当前程序的内存中,所以说这种方法是本地过滤
    var demoTest = from u in dbContext.UserInfo.ToList()
                               where u.UserId>0
                               select u;
                foreach (var item in demoTest)
                {
                    Console.WriteLine(item.Age+","+item.Name);
                }

    linq4

    下面简单分析下两种方式的本质区别:

    其实这两种方式其实是IQueryable接口集合和List集合的区别,

    1.IQueryable

    用F12看下IQueryable<> 有个IQueryable类,在类中有三个属性ElementType,Expression,Provider:

    linq3

    下图介绍了三个属性在初始化和调用时起到了什么作用,也可以解释为啥linq能to 各种(to sql,to obj,to ef,to xml):

      linq9

    通过IL看到linq表达式都编译成一个Expression,所有都转换成一个表达式树

    lin10

    2.List

    list

  • 相关阅读:
    从零搭建 jenkins 自动部署 java maven项目
    win10 Unistack 服务组 占用资源如何解决
    如何在CentOS上部署Nginx及vsftpd!
    在VS2015 添加自定义模版内容
    短信查询银行开户行信息
    oracle 数据库信息查询
    Hibernate学习---第十五节:hibernate二级缓存
    Hibernate学习---第十四节:hibernate之session线程安全
    Hibernate学习---第十三节:hibernate过滤器和拦截器的实现
    Hibernate学习---第十二节:Hibernate之锁机制&乐观锁实现
  • 原文地址:https://www.cnblogs.com/wangxiaojian/p/4352562.html
Copyright © 2020-2023  润新知