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

[ASP.net教程]Entity Framework基础—第五篇(Model First两种延迟加载)


第一种:用到的时候加载

static void Main(string[] args)    {      Query();    }    private static void Query()    {      DataModelContainer dbContext=new DataModelContainer();      IQueryable<UserInfo> userInfo = from u in dbContext.UserInfo                      where u.UserName.Contains("s")                      select u;      var resultstr = from u in userInfo              where u.UserID>0              select u;      foreach (var userinfoitem in resultstr)      {        Console.WriteLine(userinfoitem.UserID + "," + userinfoitem.UserName);      }       dbContext.SaveChanges();    }

打开sql server profiler 并运行代码看下:

ModeFirist

执行的sql脚本如图所示,它把linq组装成一个sql语句去数据库中执行,这种效率比较高

有时候大家把Linq查询出来的数据用于缓存,相当于没用,因为用到的时候,还是去执行Sql脚本

第二种延迟加载:

static void Main(string[] args)    {      //Add();      //Query();      QueryTwo();      Console.ReadKey();          }    /// <summary>    /// 第二种延迟加载    /// </summary>    private static void QueryTwo()    {      DataModelContainer dbContext = new DataModelContainer();      IQueryable<UserInfo> userInfo = from u in dbContext.UserInfo                      select u;      foreach (var userInfoItem in userInfo)//这里先进行查询一遍      {        foreach (var orderInfoItem in userInfoItem.OrderInfo)//通过导航属性进行筛选数据        {          Console.WriteLine(userInfoItem.UserName + "," + orderInfoItem.ID);        }      }    }

打开sql server profiler 并运行代码看下:

ModeFirist2

ModeFirist3

通过上图我们大致了解,通过第一个foreach 取出来userinfo中的数据,通过导航属性查询orderinfo中的数据,那么要是有大量用户呢?那需要和后台大量的交互,它的时间远远大于表连接的时间,所以性能不是很高,下面我们就解决这个问题,只跟后台交互一次,一次就把数据查询出来。

代码如下:

static void Main(string[] args)    {      //Add();      //Query();      QueryTwo();      Console.ReadKey();          }    /// <summary>    /// 第二种延迟加载    /// </summary>    private static void QueryTwo()    {      DataModelContainer dbContext = new DataModelContainer();      IQueryable<UserInfo> userInfo = from u in dbContext.UserInfo.Include("OrderInfo")//改下这里就行了,意思就是当查询UserInfo表中的数据时也把订单的一起查询出来                      select u;      foreach (var userInfoItem in userInfo)//这里先进行查询一遍      {        foreach (var orderInfoItem in userInfoItem.OrderInfo)//通过导航属性进行筛选数据        {          Console.WriteLine(userInfoItem.UserName + "," + orderInfoItem.ID);        }      }    }

打开sql server profiler 并运行代码看下:

ModeFirist4

从上图我们可以看到这种方法只和后台交互一次,就把两张表的数据都取出来了。

如果两张表中的数据都是1000W条数据,进行连接查询时,你用EF还是Include?

应该用第一种EF的方式查询,它把一个连接查询分解成若干个小的子查询,然后把数据进行组合,虽然这样查询次数变多了,但是数据库不会蹦,这种方法就是解决大表的连接查询。

Include再什么情况下用呢? 应该再数据量少的时候用,可以提高效率,减少查询次数。

查询部分列:

static void Main(string[] args)    {      //Add();      //Query();      //QueryTwo();      QueryPartColumn();      Console.ReadKey();          }    /// <summary>    /// 查询部分列    /// </summary>    private static void QueryPartColumn()    {      DataModelContainer dbContext = new DataModelContainer();      //第一种      // var partData=from u in dbContext.UserInfo             //select new{u.UserName,u.UserID,OrderCounts=u.OrderInfo.Count};      //第二种       var partData = dbContext.UserInfo.Where<UserInfo>(u => u.UserID>0).Select(u=>new       {u.UserID,u.UserName,u.OrderInfo.Count });      foreach (var item in partData)      {        Console.WriteLine(item);      }                          }

分页:

static void Main(string[] args)    {      //Add();      //Query();      //QueryTwo();      PageData();      Console.ReadKey();          }    /// <summary>    /// 数据分页    /// </summary>    private static void PageData()    {      DataModelContainer dbContext = new DataModelContainer();      var DataPage = dbContext.UserInfo                  .Where<UserInfo>(u => u.UserID > 0)                  .OrderBy<UserInfo,int>(u=>u.UserID)//默认是升序                  //.OrderByDescending<UserInfo, int>(u => u.UserID)                  //取出第一页                  .Skip(5 * (3 - 3))                  .Take(5);      foreach (var item in DataPage)      {        Console.WriteLine(item.UserID+","+item.UserName);      }    }

DataPage

上图可以看到输出一个标准的分页sql语句。

 

OK,就写到这,若有错误请您留言,谢谢!