使用tolist()或load()时延迟加载不可接受的行为 [英] Lazy loading unacceptable behavior when using tolist() or load()

查看:158
本文介绍了使用tolist()或load()时延迟加载不可接受的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习EF。练习时我注意到Lazy Loading的一个奇怪的行为。



我读过,默认启用延迟加载,只有当导航属性标记为虚拟时才可以使用LazyLoadingEnabled =在上下文中配置。

所以,我决定通过将开关设置为关闭来关闭延迟加载,即LazyLoadingEnabled = false。



以下是在此之后尝试访问dbset的代码:

I am learning EF. While practicing I noticed a strange behavior for Lazy Loading.

I read, Lazy loading is enabled by default and can work only if navigation properties are marked virtual along with LazyLoadingEnabled = ture in context's configuration.
So, I decided to turn off lazy loading by setting the switch to off i.e., LazyLoadingEnabled = false.

Here is the code that tried to access the dbset after then:

if (context == null)
         context = new InventoryEntities(".");
     context.Configuration.LazyLoadingEnabled = false;
     List<STOCK_ITEM_GROUPS> res = (from groups in context.STOCK_ITEM_GROUPS
                                  orderby groups.name
                                  select groups).ToList<STOCK_ITEM_GROUPS>();           
           string msg = "";
           foreach (var groups in res)
               msg += "Name: " + groups.name + "\tParent Name: " +                 (groups.STOCK_ITEM_GROUPS2 == null ? "none" : groups.STOCK_ITEM_GROUPS2.name) + Environment.NewLine;
              
           Console.WriteLine(msg);





以下是为STOCK_ITEM_GROUPS生成的dbset:



Below is the dbset generated for STOCK_ITEM_GROUPS:

public partial class STOCK_ITEM_GROUPS
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public STOCK_ITEM_GROUPS()
        {
            this.STOCK_ITEM_GROUPS1 = new HashSet<STOCK_ITEM_GROUPS>();
            this.STOCK_ITEM_MASTER = new HashSet<STOCK_ITEM_MASTER>();
        }
    
        public short id { get; set; }
        public string name { get; set; }
        public Nullable<short> idParent { get; set; }
        public bool itemAddable { get; set; }
        public bool isactive { get; set; }
        public System.DateTime active_timestamp { get; set; }
        public Nullable<System.DateTime> deactivation_timestamp { get; set; }
        public byte[] rv { get; set; }
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<STOCK_ITEM_GROUPS> STOCK_ITEM_GROUPS1 { get; set; }
        public virtual STOCK_ITEM_GROUPS STOCK_ITEM_GROUPS2 { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<STOCK_ITEM_MASTER> STOCK_ITEM_MASTER { get; set; }
    }





现在,理想情况下我不应该收到导航属性的数据



Now, ideally I should not receive data for navigation property

public virtual STOCK_ITEM_GROUPS STOCK_ITEM_GROUPS2 { get; set; }

,因为,懒惰加载未启用。但是,我收到了相关数据!

我尝试在上下文的构造函数中关闭延迟加载但没有帮助。



我可能会遗漏任何概念性的东西,或者还有其他我不知道的东西。

查看调试器生成的查询,我发现只有一个查询来查找数据库中的所有数据。

因此,也没有多个查询,但有相关数据。我不明白我哪里错了。



我尝试过:



我在DbSet上尝试使用Load()方法,它也返回与ToList()返回相同的结果。

搜索谷歌但发现只有1条评论,这不是真正的条件我我在,这里是链接:

c# - 实体框架 - 延迟加载即使使用ToList() - Stack Overflow [ ^ ]

, since, lazy loading is not enabled. But, I am receiving the related data!
I tried turning lazy loading off in the context's constructor as well but no help.

I might be missing any conceptual thing or there is something else I dont really know.
Looking at debugger for queries generated, I find only one query that looks for all the data from database.
thus, there are not multiple queries too but there is the related data. I dont understand where I am going wrong.

What I have tried:

I tried the same with Load() method on DbSet, it also returns same result as ToList() returns.
Searched on google but found only 1 comment, which is not really the condition I am in, here is the link for that:
c# - Entity Framework - Lazy Loading working even with ToList() - Stack Overflow[^]

推荐答案

怀疑这是因为你正在使用自引用导航属性,并将整个集合加载到内存中。



我找不到EF6的等效文档,但是EF Core文档中有一个注释ld解释这种行为:

I suspect that this is because you're using self-referencing navigation properties, and loading the entire set into memory.

I can't find the equivalent documentation for EF6, but the EF Core documentation has a note that would explain this behaviour:

实体框架核心将自动将导航属性修复到先前加载到上下文实例中的任何其他实体。因此,即使您没有明确包含导航属性的数据,如果以前加载了部分或全部相关实体,仍可能会填充该属性。

Entity Framework Core will automatically fix-up navigation properties to any other entities that were previously loaded into the context instance. So even if you don't explicitly include the data for a navigation property, the property may still be populated if some or all of the related entities were previously loaded.



如果你看一下而不是 STOCK_ITEM_MASTER 集合,它不应该自动加载。


If you look at the STOCK_ITEM_MASTER collection instead, it should not be loaded automatically.


禁用延迟加载不会停止相关数据加载,它会停止它按需加载,所以它立即被加载。您可能更好地使用包含功能来根据每个案例指定哪些数据是延迟加载的。它将明确表示什么是延迟加载和什么不是。
Disabling lazy loading doesn't stop related data loading, it stops it being loaded on-demand, so instead it is loaded right away. You might be better using the "Include" feature to dictate what data is lazy-loaded or not on a per-case basis. It will make it explicit what is being lazy loaded and what isn't.


这篇关于使用tolist()或load()时延迟加载不可接受的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆