• 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,就写到这,若有错误请您留言,谢谢!

  • 相关阅读:
    mysql完全卸载教程(图文详细)
    windows:安装django
    01 Java的NIO三大组件以及buffer的原理以及应用
    16 JDK8的concurrenthashmap的原理介绍
    07 Java源码字节码层面简单分析
    06 Java字节码的基础知识
    05 Java的class文件的组成介绍
    04 G1垃圾回收器的介绍以及垃圾回收调优的基础知识和简单案例
    03 JVM中垃圾回收算法以及典型的垃圾回收器
    02 Java的引用类型以及应用场景
  • 原文地址:https://www.cnblogs.com/wangxiaojian/p/4364584.html
Copyright © 2020-2023  润新知