你的位置:首页 > ASP.net教程

[ASP.net教程]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

  linq9

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

lin10

2.List

list