Entity framework 4 实体框架,调用ToList()时会自动加载FK对象吗?
我有点搞不懂加载有多懒 例如,如果我有supplier对象,它将Address foreign对象作为属性,如下所示:Entity framework 4 实体框架,调用ToList()时会自动加载FK对象吗?,entity-framework-4,lazy-loading,poco,Entity Framework 4,Lazy Loading,Poco,我有点搞不懂加载有多懒 例如,如果我有supplier对象,它将Address foreign对象作为属性,如下所示: public class Supplier { public int ID { get; set; } [Required] public string FullName { get; set; } public string TaxNumber { get; set; } public virtu
public class Supplier
{
public int ID { get; set; }
[Required]
public string FullName { get; set; }
public string TaxNumber { get; set; }
public virtual Address DeliveryAddress { get; set; }
}
当我在以下位置设置断点时:
var suppliers = dbContext.Supplier.ToList();
我可以看到地址信息可供var供应商使用,等等。当我扩展DeliveryAddress属性时,它是可用的,这是否意味着所有FK对象都已加载?但另一方面,对于右侧的查询,我可以在断点处从Visual Studio查看,如下所示:
{SELECT
[Extent1].[ID] AS [ID],
[Extent1].[FullName] AS [FullName],
[Extent1].[TaxNumber] AS [TaxNumber],
[Extent1].[DeliveryAddress_ID] AS [DeliveryAddress_ID]
FROM [dbo].[Suppliers] AS [Extent1]}
这意味着查询本身根本不会加载Address对象
那么谁在加载FK对象呢?ToList()还是VS调试器
关于如何确认是否为延迟加载的其他建议
注意:现在我通过两个ToList调用确认了延迟加载的工作,一个设置为Lazy-loading-off,另一个设置为Lazy-loading-on。有人能告诉我一种方法,知道在什么时候为FK属性发送了另一个延迟加载查询吗?VS调试器加载相关对象,并且它发生在第二个SQL查询中,而不是您在问题中显示的查询。在调试器中钻取address对象时,调试器将访问该对象的属性以显示其值。访问此对象会触发延迟加载和第二个SQL查询 编辑 这是因为父对象不是您的
供应商
类型,而是从供应商
派生的类(“代理”)。这个派生类是在运行时动态创建的,并且有一些神秘的自动生成的名称(您应该在调试器中看到这个类名)。此动态类与基本供应商
具有相同的属性,但它重载了DeliveryAddress
属性。(这就是为什么这些导航属性必须是虚拟的
,否则无法重载的原因。)查询使用FK列值,该值已通过供应商查询获取,并通过该值检索地址
重载的DeliveryAddress
属性的新getter,当您或调试器使用supplier访问该属性时调用该属性。DeliveryAddress
包含运行时生成的代码,该代码运行SQL查询以从数据库加载相关对象。派生代理类包含各种其他内部成员,特别是对上下文/数据库连接的引用(以便能够运行查询)和一个标志,该标志指示代理对象已加载导航属性,这样,当您第二次访问DeliveryAddress
时,它就不会运行第二次冗余查询
简而言之,这就是POCOs延迟加载的工作方式。您如何确定DeliveryAddress已被急切/非延迟加载?您确定只向数据库发送了1个查询吗?您可以启动SQL Profiler来查看发送到数据库的查询。您好,我如何启动SQL Profiler?我使用的是SQLServer2008R2,而且似乎没有可用的SQL事件探查器菜单。我只能看到:导入和导出、服务器管理工作室、配置工具、集成服务?@Salauma,感谢您的额外解释,原始答案本身很好,但有点明显。您能否建议一种方法,以确定何时发送DeliveryAddress属性的查询?SQL Profiler的问题是,我似乎需要先安装它。@pstar:当您单击VS debugger对象树中的+节点以钻取供应商的交货地址时,就会发送查询。发送的查询类似于:
SELECT*FROM addresstable,其中AddressId=DeliveryAddress\u ID
@Salauma,我想看到的是对FK对象的查询。我希望除非访问FK属性,否则DeliveryAddress的查询不会启动,但无法确认。