zoukankan      html  css  js  c++  java
  • MVC 之 EF延迟加载

    所谓EF延迟加载,就是使用Lamabda或Linq查询数据时,EF并不会将数据直接查询出来,而是在用到的这个查询结果的时候才会加载到内存中。延迟加载也可以理解成 按需加载,顾名思义,就是按照所需的数据,加载数据。那么为什么要使用延迟加载?使用延迟加载的优缺点是什么?下面通个几个例子来说明。

    首先用到了两张非常简单的表

    T_Artcle 文章表,T_User用户表,用UserID作为外键关联,插入下面的数据

    INSERT INTO T_User VALUES('nee32')
    INSERT INTO T_Artcle VALUES('test title',1)

    然后新建一个控制台应用程序,导入这两张表,注意添加表的时候把确定所生成对象名称的单复数形式勾上

    一、EF中的查询Where与集合List中的Where的区别

    EF中的where

    EF中的Where返回的是一个IQueryable,我们再写一个list集合,看看返回的是什么

    奇怪,都是Where方法,但是返回的结果却完全不一样,原因是因为 集合的查询方法Where是来自System.Linq.Enumerable里给IEnumerable接口添加的扩展方法,而EF上下文中的DBSet<T>里的查询方法Where来自System.Linq.Queryable里给IQueryable接口添加的扩展方法,虽然都是调用的Where方法,但是这两个方法完全不一样。因为IQueryable这个接口,所以就支持延迟查询。

    二、即时查询与延迟查询

    1、即时查询

    首先在执行查询的时候打一个断点

    再用 sql server profiler监听 执行的sql

    可以看到,执行完断点就马上查询了数据库,所以上面的查询是即时的

    2、延迟查询

    我们改一下上面的代码

    设置断点再用 sql server profiler监听,发现断点之前并没有执行任何sql

    只有在用到使用它的时候 T_User user = query.FirstOrDefault() 

    延迟查询的优点:例如有一个博客查询页面,上面有发布时间、关键字、分类等查询条件,当查询条件个数不确定的时候,where并没有立即去查询数据库,而是把所有的条件都确定好之后,才根据这些where条件生成一条相应的sql去查询数据库。

    3、外键实体的延迟加载

    本质:对与外键属性,EF会在用到这个外间属性的时候才去查询相应的表

    先在EDM实体模型中看下用户与文章的关系

    生成的类代码如下:

     public partial class T_Artcle
        {
            public int Id { get; set; }
            public string Title { get; set; }
            public int UserID { get; set; }
        
            public virtual T_User T_User { get; set; }
        }
    public partial class T_User
        {
            public T_User()
            {
                this.T_Artcle = new HashSet<T_Artcle>();
            }
        
            public int Id { get; set; }
            public string UserName { get; set; }
        
            public virtual ICollection<T_Artcle> T_Artcle { get; set; }
        }

    edmx 帮我们生成了相应的主外键关系

    例如,查询出 文章表 ID为1的 的文章用户

    static void Main(string[] args)
            {
                Nee32Entities db = new Nee32Entities();//创建一个上下文对象
                var query = db.T_Artcle.Where(u => u.Id == 1);
                T_Artcle artcle = query.FirstOrDefault();//只查询了文章表
                Console.WriteLine(artcle.T_User.UserName);//查询了文章对应的用户表
                Console.ReadKey();
            }

    在Console.WriteLine(artcle.T_User.UserName);这一行设置断点,使用 sql server profiler监听一下

    这里只是查询了文章表,并没有查询用户表,继续逐步执行

    这个时候EF去用用户表了,因为这里用到了文章表的外键属性,程序输出 nee32

  • 相关阅读:
    UVa 116 单向TSP(多段图最短路)
    POJ 1328 Radar Installation(贪心)
    POJ 1260 Pearls
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    UVa 1620 懒惰的苏珊(逆序数)
    POJ 1018 Communication System(DP)
    UVa 1347 旅行
    UVa 437 巴比伦塔
    UVa 1025 城市里的间谍
  • 原文地址:https://www.cnblogs.com/notevar/p/5759840.html
Copyright © 2011-2022 走看看