首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么有时是急迫的负荷,有时是懒惰的负荷?

为什么有时是急迫的负荷,有时是懒惰的负荷?
EN

Stack Overflow用户
提问于 2013-04-17 12:58:56
回答 1查看 1.4K关注 0票数 3

我有一个用于搜索的通用基存储库方法(为清晰起见而进行了修剪):

代码语言:javascript
运行
AI代码解释
复制
public class Repository<TRepository> : IRepository<TRepository>
        where TRepository : class, IEntity, new()
{    
     public virtual IQueryable<TRepository> SearchFor(Expression<Func<TRepository, bool>>   predicate, Expression<Func<TRepository, bool>> orderbylinq = null)
    {
        if (orderbylinq == null)
        {
            return DbSet.Where(predicate);
        }
        else
        {
            return DbSet.Where(predicate).OrderBy(orderbylinq);
        }
    }

}

我有一个派生的存储库类:

代码语言:javascript
运行
AI代码解释
复制
public class TimeDetailRepository : Repository<TimeDetail>

在我的服务层中,有一个调用SearchFor方法的类:

代码语言:javascript
运行
AI代码解释
复制
private TimeDetailRepository _timeDetailRepository;

        public ManageTimeDetailsAppServ()
            : base(new TimeDetailRepository())
        {
            _timeDetailRepository = new TimeDetailRepository();
        }
IQueryable<TimeDetail> timeDetails2 = _timeDetailRepository.SearchFor(
                    x => x.Id == 3214);

在本例中,timeDetails2是完全加载的(所有相关实体都已加载)。

但是,我有另一个类(基本服务层类)进行相同的SearchFor调用,但它没有加载相关实体:

代码语言:javascript
运行
AI代码解释
复制
IQueryable<TRepository> dbEntity = _repository.SearchFor(x => x.Id == result.Value);

在这两个调用中,我都试图创建一个视图模型,该模型利用来自相关实体的属性值。为什么要在一种情况下而不是另一种情况下装载它们?这是相同的实体TimeDetail,相同的基础存储库类?

在调试器中看到的图像。为什么某些相关实体会被加载(比如设施,和TimeDetailStatus),而其他实体则不会被加载(比如OrderHeader或客户)

更新

我查看了正在生成的查询,它们看起来都很相似,即它们没有连接到另一个tables...so --上下文是否可能已经包含了来自一些相关实体的一些缓存行,这就是它们是如何被包含的?

EN

回答 1

Stack Overflow用户

发布于 2013-04-17 14:10:27

除非在集合上使用.Include()方法,否则EF将执行延迟加载。因为你没有那样做,所以你不会立即得到它们,但是当你召唤它们时,你会懒洋洋地把它们装上。

但是,只有在对象上下文仍然打开的情况下,这才有效。如果上下文没有了,那么连接到数据库的能力就消失了,所以属性都是空的。

我的猜测是,你所看到的差异与你如何保持周围的环境有关。这很难说,因为你没有显示你的背景,但我会从那里开始。

编辑

不确定这是否与你的问题有任何关系,但我只是想澄清懒惰加载的东西。下面是我最喜欢的EF示例:两个表:作者(AuthorId,AuthorName)和图书(BookId,AuthorId(FK),BookTitle)

代码语言:javascript
运行
AI代码解释
复制
/*  1 */ static void Main(string[] args)
/*  2 */ {
/*  3 */    Book book;
/*  4 */    using (var context = new SampleDbEntities())
/*  5 */    {
/*  6 */        book = context.Books.Single(b => b.BookId == 1);
/*  7 */    }
/*  8 */
/*  9 */    try
/* 10 */    {
/* 11 */        Console.WriteLine(book.Author.AuthorName);
/* 12 */    }
/* 13 */    catch (Exception ex)
/* 14 */    {
/* 15 */        Console.WriteLine(ex.Message);
/* 16 */    }
/* 17 */ 
/* 18 */    Console.ReadLine();
/* 19 */ }

如果您按-原样运行此代码,则会发生以下情况:

  • 第6行只查询Books表,并使用匹配的记录填充book变量。数据库中从未触及过Authors表。
  • 在第7行之后,将释放上下文,这意味着数据访问已经死亡。
  • 第11行抛出一个试图访问Author属性的异常。

但是,如果您使用调试器并在第7行停止,只需在一瞬间查看图书变量,它将立即查询数据库中的Authors表(在调试器中),并在该对象上填充Author属性。这就是我所说的延迟加载的意思--当您实际访问该属性时,即使在调试器中,当上下文处于活动状态时,它也会发出一个新的数据库调用。现在您可以继续代码了,第11行就可以了,作者的名字将被打印出来。

因此,基本上,当涉及到EF时,不要信任调试器。它懒散地加载数据,尽管它看起来不像这样。要想搞清楚到底发生了什么,最好的办法就是启动,并查看哪些查询正在运行。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16070148

复制
相关文章
java数组如何赋值_java数组如何赋值
Java 语言中数组必须先初始化,然后才可以使用。所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值。
全栈程序员站长
2022/09/13
4.1K0
java数组如何赋值_java数组如何赋值
如何给结构体内声明的二维数组赋值
最近在用C++做一个象棋小游戏,为了规避全局变量的使用,想使用结构体来声明需要使用的数据。给其中用来存储棋盘信息的二维数组赋值时却遇到了问题:
英雄爱吃土豆片
2020/10/29
2.6K0
Java基础:数组的声明,循环,赋值,拷贝。
下面,语句就是声明了一个可以存储100个整数的数组。可以根据你的实际需求,更换int类型为你需要的数据类型。
呆呆
2021/10/04
1.1K0
Mysql 声明变量并赋值
注意上面两种赋值符号,使用set时可以用“=”或“:=”,但是使用select时必须用“:=赋值”
一个会写诗的程序员
2018/08/17
4.1K0
MySQL变量声明、赋值和使用
上面两种赋值符号,使用set时可以用“=”或“:=”,但是使用select时必须用“:=赋值”
Java那些事儿
2020/07/21
3.5K0
java对象组声明_如何在Java中声明对象数组?
可以创建对象类数组,该数组可以接受任何类型的对象。在此类数组上运行期间,可以使用instanceof运算符。
全栈程序员站长
2022/08/30
3.9K0
Java中如何声明数组「建议收藏」
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/137070.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/05
1.8K0
Java数组赋值
String [] word = {"hello", "world", "java"}; String [] dest = new String[3]; dest = words; words[0] = "nihao"; for(String t: dest){ System.out.println(t); } String [] dest2 = {"12","23","
一灰灰blog
2018/02/06
2.1K0
数组解构赋值
倘若A代表人生的成功,那么公式是:A =X+Y+Z。X是工作,Y是游戏,z是保持缄默。——(美)爱因斯坦 我们以前从一个数组中获取第一项,可能是如下写法: let list = [1,2,3] let i = list[0] 有了解构赋值,可以如下写法: let list = [1,2,3] let [i] = list 如果稍微复杂点,例如下面这样从对象中取出来数组: let ruben = {hobby:['anime']} let favorite = ruben.hobby[0] 就可以写成
阿超
2022/08/17
1.5K0
Java 数组声明
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/137260.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/05
8370
VBA数组(二)声明数组
大家好,上节介绍了数组的维度,索引号、上界和下界的知识,本节继续介绍数组的基础知识,包括数组的分类,以及如何声明数组。关于数组的内容相对抽象,会尽量介绍详尽。
无言之月
2019/10/13
3.5K0
VBA数组(三)数组赋值
大家好,上节介绍了在使用数组之前如何声明数组,本节就来介绍静态数组如何赋值。(动态数组会单独一节讲解)
无言之月
2019/10/13
12.5K0
解构赋值的作用_数组解构赋值
数组解构是非常简单简洁的,在赋值表达式的左侧使用数组字面量,数组字面量中的每个变量名称映射为解构数组的相同索引项
全栈程序员站长
2022/11/03
3.9K0
java如何键盘录入数组_从键盘输入给数组赋值
有时候在编写Jave的时候需要键盘输入一个数组,本小白也是看了几篇博客后才知道了如何在自己的程序中进行键盘输入,废话不多说,直接上代码: 第一种方法:(不限制输入数组的长度)
全栈程序员站长
2022/08/03
3.5K0
java如何键盘录入数组_从键盘输入给数组赋值
Matlab赋值_matlab二维数组赋值
y=[106。42 108。26 109。58 109。5 110 109。93 110。49 110。
全栈程序员站长
2022/11/10
2.2K0
【说站】java数组赋值
在数组的学习方面,我们不光有创建、初始化等操作,赋值也是操作数组必学的知识点。在赋值方面有两种方式,一种是先定义再赋值,另一种是边定义边赋值。
很酷的站长
2022/11/23
1.6K0
【说站】java数组赋值
Java之数组赋值机制
基本数据类型赋值,这个值就是具体的数据,而且相互不影响。 int n1 = 2; int n2 = n1; 数组在默认情况下是引用传递,赋的值是地址。 看一个案例,并分析数组赋值的内存图(重点, 难点. )。 ArrayAssign.java int[] arr1 = {1,2,3}; int[] arr2 = arr1; //基本数据类型赋值, 赋值方式为值拷贝 //n2的变化,不会影响到n1的值 int n1 = 10; int n2 = n1; n2 = 80; System.out
兮动人
2021/06/11
1.4K0
Java之数组赋值机制
Go 专栏|变量和常量的声明与赋值
上篇文章介绍了环境搭建,并完成了学习 Go 的第一个程序 Hello World。这篇文章继续学习 Go 的基础知识,来看看变量,常量的声明与赋值。
AlwaysBeta
2021/09/02
1.1K0
Go 专栏|变量和常量的声明与赋值
数组的声明以及分类
②$arr=array(key1=>value1,key1=>value2,key1=>value3);
十月梦想
2018/08/29
7370
Python-声明数组(列表)
在 Python 中,数组被称为列表(list),定义一个列表需要使用中括号 []
用户9006224
2023/04/22
7290

相似问题

通过javascript播放mp4视频

20

使用jquery播放视频的lightbox效果?

23

在WordPress插件的Lightbox中播放YouTube视频

15

如何在html视频标签中播放mp4视频,视频是通过multer上传的

24

lightbox中的视频有问题吗?

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档