当前位置:  开发笔记 > 编程语言 > 正文

EF6中的Eager,Lazy和显式加载

如何解决《EF6中的Eager,Lazy和显式加载》经验,为你挑选了2个好方法。

我已经阅读了本教程和本文,但我并不完全理解每种加载类型的用法.

我解释

我有这个POCO:

public partial class dpc_gestion
{
    public dpc_gestion()
    {
        this.ass_reunion_participant = new HashSet();
        this.dpc_participant = new HashSet();
        this.dpc_reunion = new HashSet();
    }

    public int dpc_id_pk { get; set; }
    public Nullable dpc_id_gdp_fk { get; set; }
    public Nullable dpc_id_theme { get; set; }
    public int dpc_id_animateur_fk { get; set; }
    public Nullable dpc_date_creation { get; set; }
    public Nullable dpc_date_fin { get; set; }
    public Nullable dpc_date_engag_anim { get; set; }
    public Nullable dpc_flg_let_engag_anim { get; set; }
    public Nullable dpc_flg_fsoins_anim { get; set; }
    public virtual ICollection ass_reunion_participant { get; set; }
    public virtual theme_dpc theme_dpc { get; set; }
    public virtual gdp_groupe_de_pair gdp_groupe_de_pair { get; set; }
    public virtual ICollection dpc_participant { get; set; }
    public virtual ICollection dpc_reunion { get; set; }
}

我理解这个:

    对于延迟加载:因为加载是惰性的,如果我调用dbset,则不会加载dpc_gestion所有导航属性.这种类型的负载是性能和响应性最好的.它默认启用,如果我想重新启用它,我必须设置:

    context.Configuration.ProxyCreationEnabled = true;    
    context.Configuration.LazyLoadingEnabled = true;
    

    对于急切加载 它不是懒惰的:它在我加载时加载了所有导航属性dpc_gestion.可以使用include方法加载导航属性.要启用此加载类型:

    context.Configuration.LazyLoadingEnabled = false;
    

    对于显式加载 它就像热切加载但我们使用Load方法而不是include.

所以我想知道:

    如果这个小简历是真的吗?

    如果是真的,那么eager和explicit加载有什么区别?

    如果我使用延迟加载,我打电话给例如dpc_gestion.dpc_participant,导航属性是否加载?或者我会得到一个例外?

    是否有一种情况是,在性能和响应性方面,预先加载或显式加载比延迟加载更好?

谢谢



1> Salah Akbari..:

如果这个小简历是真的吗?

是.

如果是真的,那么eager和explicit加载有什么区别?

急切加载延迟加载相反,但显式加载类似于延迟加载,除了:您在代码中显式检索相关数据; 访问导航属性时不会自动执行此操作.您可以通过获取实体的对象状态管理器条目并调用Collection.Load集合的Reference.Load方法或包含单个实体的属性的方法来手动加载相关数据.

来自techblog:

渴望加载:

渴望加载延迟加载相反,它是:加载一组特定相关对象以及查询中显式请求的对象的过程.

明确加载:

显式加载定义为:当查询返回对象时,不会同时加载相关对象.默认情况下,在使用导航属性上的Load方法显式请求之前,不会加载它们.

和:

如果我使用延迟加载,我打电话给例如dpc_gestion.dpc_participant,导航属性是否加载?或者我会得到一个例外?

您没有得到任何异常,导航属性应该加载.

是否有一种情况是,在性能和响应性方面,预先加载或显式加载比延迟加载更好?

当您需要主表的所有检索行的相关数据时,热切加载通常更有效.而且当关系不是太多时,急切加载将是减少服务器上进一步查询的良好做法.但是当你知道你不会立即需要一个属性时,延迟加载可能是一个不错的选择.而且,如果您的数据库上下文被丢弃并且无法再进行延迟加载,那么急切加载也是一个不错的选择.例如,请考虑以下事项:

public List GetAuctions()
{
    using (DataContext db = new DataContext())
    {
        return db.Auctions.ToList();
    }
}

在调用此方法之后,您无法懒惰地加载相关实体,因为它db已被释放,因此Eager Loading将是更好的选择.

还有一点需要注意:延迟加载会产生多个SQL请求,而Eager正在加载一个请求加载数据.渴望加载也是解决ORM中n + 1选择问题的不错选择.看看这篇文章:什么是n + 1选择问题?



2> Domysee..:

问题1和2:

您对延迟加载急切加载的解释是正确的.显式加载
的使用与您描述的有点不同.

EntityFramework返回IQueryable对象,它基本上包含对数据库的查询.但这些只有在第一次枚举时才会执行.
Load执行查询,以便将结果存储在本地.
呼叫Load与呼叫ToList和丢弃一样List,没有创建的开销List.

问题3:

如果你使用延迟加载,EntityFramework将负责为你加载导航属性,这样你就不会得到异常.
请记住,这可能需要一段时间,并使您的应用程序无响应.

问题4:

在断开连接的情况下(例如网络应用程序),您不能使用延迟加载,因为这些对象被转换为DTO,然后不被跟踪EntityFramework.

此外,如果您知道要使用导航属性,那么应该急切地加载它,这样您就不必等到从数据库加载它们.
例如,假设您将结果存储在列表中并将其绑定到WPF DataGrid.如果DataGrid访问尚未加载的属性,则在显示该属性之前,用户会遇到明显的超时.此外,应用程序在加载期间不会响应(如果您不加载异步).


还要记住,对于延迟加载,上下文必须是活动的,否则将抛出异常.我会说,在断开连接的场景中,只要您构建将要序列化的对象图,您就可以*使用延迟加载,尽管通过"Include"或"加载"显式加载您需要的所有内容更为常见`.
推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有