2014-03-27 186 views
1

当我使用实体框架它创建对象为数据库中的所有数据例如context.Customers.Load();它会创建1000个客户对象,然后5000订单对象,如果是这样,它不会使用很多记忆?c#实体框架加载实体

回答

2

您应该从您需要的时刻创建EF上下文,并从您完成的那一刻开始处理它(工作单元,using语句)。当然,你应该只查询你需要的东西 - 我怀疑你在一个请求中需要5000个订单。

是的,EF为每个查询创建实体。导航属性没有加载,你必须专门包含这些或使用延迟加载(但我会避免这种情况)。

+0

第一MSDN上:“当的Windows Presentation Foundation(WPF)或Windows窗体的工作,每使用形式的上下文实例,就可以使用更改跟踪功能这方面提供了”,所以我使用WPF,和什么如果我需要所有客户的列表(DataGrid)或订单 – Lerner

+0

然后确保您的问题包含足够的信息,我们无法猜测。对我而言,您的WPF应用程序直接访问数据库听起来很诡异。即使那样,你也不需要5000个订单。 –

+0

嗨,它不是数字5000,我想知道的是,如果EF在表中查询我创建的表中的每个原料的内存对象,并且你没有回答我,如果我需要一个所有客户的列表是什么?谢谢 – Lerner

1

除了L-Three的回复之外,使用using声明可能不适合所有情况。例如,对于桌面应用程序,保持连接打开而不是始终打开和关闭连接以查询简单数据更有意义。确保在完成时处理它很重要。一个好的地方是听窗口上的Closing事件。触发时,您可以处置DbContext

如果您不缩小查询的范围,例如:使用where子句,EF会在尝试访问数据库时加载数据库中的所有对象。通过执行var query = Db.Users;,您实际上并未查询数据库,您只是创建了一条查询,当您尝试访问数据时将发送该查询。如果你做了var query = Db.User.ToList();,那么是的,查询将被执行,并且所有User对象将被查询,映射并返回。所以如果你有100万行,EF会尝试加载100万条记录。在大多数情况下,没有理由返回数据库中的所有对象,但始终存在边缘案例。

取决于您如何配置上下文,子女关系有点不同。默认情况下,我相信EF使用了一种叫做的延迟加载延迟加载允许EF用特殊代码覆盖您的属性,直到您尝试访问它们时才会加载子对象。在另一方面,你可以做什么叫做急切加载。这使您可以在查询中包含所有子对象,从而减少访问数据库的次数。在大多数情况下,应该使用急切加载,因为您应该知道应用程序将显示给用户的信息。

如果你只曾经使用延迟加载你可以得到一些麻烦,因为它只是工作,它可以通过一些简单的创建N + 1周的语句会导致性能问题的道路。

+0

因此,如果我想要列表框中的客户列表,并且比用户选择客户时显示该客户的订单datagrid(例如QuickBooks有一个所有事务的列表)EF会为每个订单在内存中创建对象吗?!这是不是内存使用问题? – Lerner

+0

是的,EF会加载所有的客户,并会记录它在内存中的变化。当您访问客户对象的导航属性时,它会将这些属性加载到内存中,并跟踪对这些内容的更改。它**可能会成为一个内存使用问题,具体取决于返回的实体数量和随后的对象图形。还有加载时间的问题。 – Justin

+0

当我选择第二个客户时,第一个客户的订单是否会被垃圾收集? – Lerner