我已经阅读了本教程和本文,但我并不完全理解每种加载类型的用法.
我解释
我有这个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
,导航属性是否加载?或者我会得到一个例外?
是否有一种情况是,在性能和响应性方面,预先加载或显式加载比延迟加载更好?
谢谢
如果这个小简历是真的吗?
是.
如果是真的,那么eager和explicit加载有什么区别?
急切加载与延迟加载相反,但显式加载类似于延迟加载,除了:您在代码中显式检索相关数据; 访问导航属性时不会自动执行此操作.您可以通过获取实体的对象状态管理器条目并调用Collection.Load
集合的Reference.Load
方法或包含单个实体的属性的方法来手动加载相关数据.
来自techblog:
渴望加载:
渴望加载与延迟加载相反,它是:加载一组特定相关对象以及查询中显式请求的对象的过程.
明确加载:
显式加载定义为:当查询返回对象时,不会同时加载相关对象.默认情况下,在使用导航属性上的Load方法显式请求之前,不会加载它们.
和:
如果我使用延迟加载,我打电话给例如
dpc_gestion.dpc_participant
,导航属性是否加载?或者我会得到一个例外?
您没有得到任何异常,导航属性应该加载.
是否有一种情况是,在性能和响应性方面,预先加载或显式加载比延迟加载更好?
当您需要主表的所有检索行的相关数据时,热切加载通常更有效.而且当关系不是太多时,急切加载将是减少服务器上进一步查询的良好做法.但是当你知道你不会立即需要一个属性时,延迟加载可能是一个不错的选择.而且,如果您的数据库上下文被丢弃并且无法再进行延迟加载,那么急切加载也是一个不错的选择.例如,请考虑以下事项:
public ListGetAuctions() { using (DataContext db = new DataContext()) { return db.Auctions.ToList(); } }
在调用此方法之后,您无法懒惰地加载相关实体,因为它db
已被释放,因此Eager Loading将是更好的选择.
还有一点需要注意:延迟加载会产生多个SQL请求,而Eager正在加载一个请求加载数据.渴望加载也是解决ORM中n + 1选择问题的不错选择.看看这篇文章:什么是n + 1选择问题?
问题1和2:
您对延迟加载和急切加载的解释是正确的.显式加载
的使用与您描述的有点不同.
EntityFramework
返回IQueryable
对象,它基本上包含对数据库的查询.但这些只有在第一次枚举时才会执行.
Load
执行查询,以便将结果存储在本地.
呼叫Load
与呼叫ToList
和丢弃一样List
,没有创建的开销List
.
问题3:
如果你使用延迟加载,EntityFramework
将负责为你加载导航属性,这样你就不会得到异常.
请记住,这可能需要一段时间,并使您的应用程序无响应.
问题4:
在断开连接的情况下(例如网络应用程序),您不能使用延迟加载,因为这些对象被转换为DTO,然后不被跟踪EntityFramework
.
此外,如果您知道要使用导航属性,那么应该急切地加载它,这样您就不必等到从数据库加载它们.
例如,假设您将结果存储在列表中并将其绑定到WPF DataGrid.如果DataGrid访问尚未加载的属性,则在显示该属性之前,用户会遇到明显的超时.此外,应用程序在加载期间不会响应(如果您不加载异步).