第一种:用到的时候加载
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 并运行代码看下:
执行的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 并运行代码看下:
通过上图我们大致了解,通过第一个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 并运行代码看下:
从上图我们可以看到这种方法只和后台交互一次,就把两张表的数据都取出来了。
如果两张表中的数据都是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); } }
上图可以看到输出一个标准的分页sql语句。
OK,就写到这,若有错误请您留言,谢谢!