zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    android的FATAL EXCEPTION: main错误
    ORA12560: TNS: 协议适配器错误
    BroadcastReceiver应用详解
    using C# 详解
    mysqlproxy0.8版本读写分离测试总结
    Mysql SHOW PROCESSLIST Sending data
    [转载]大型网站运维探讨和心得
    找出并optimization表
    mysql中普通索引和唯一索引的效率对比
    ps aux 中STAT 解释
  • 原文地址:https://www.cnblogs.com/wangxiaojian/p/4352562.html
Copyright © 2011-2022 走看看