[英]Entity framework DbContext and lazy loading
你的期望和你目前的执行是相互矛盾的。
我想在我的应用程序中使用延迟加载
ObjectContext 实例已被释放,无法再使用
错误消息清楚地表明您在关闭上下文后仍然希望访问数据(通过延迟加载),这是不可能的。
这里有两种解决方案:
1. 确保在完成延迟加载数据之前不要关闭上下文。
按照设计,这就是您假设进行延迟加载的方式。 假设您使用的是using
语句,请确保您只在using
块内获取数据。
但是,您会注意到,在大型代码库中,很难确保上下文保持打开足够长的时间。 这就是为什么我敦促您考虑其他选择:
2. 切换到急切加载。
延迟加载是一种非常简单的方法,并且在小型应用程序中运行良好(例如,当我编写一个短期使用工具来帮助我时)。 然而,对于较大的基础设施,延迟加载开始导致容易犯但很难调试的错误。
虽然预先加载并不能避免这些运行时异常,但与必须弄清楚哪些数据在什么时候被延迟加载相比,您将遇到的异常(忘记了Include
语句)将更容易调试。
我不会告诉您不能使用延迟加载,但您确实需要了解这会导致的复杂性。 对于足够大的代码库,跟踪是否过早关闭上下文变得几乎无法维护。
维护这个(和调试所有你没有阻止的问题)的成本将大大超过预先加载所需的稍微冗长的代码。
延迟加载的替代方案 - 每个查询使用DbContext
实例。
仅加载当前操作所需的数据,尤其是在 Web 应用程序中,应用程序以小块“请求-响应”工作。
DbContext
只是一个对象,它的创建是芯片。
延迟加载会很快引入问题,例如“N + 1”查询。
使用每个查询实例,您将能够充分利用异步查询,您几乎可以同时执行多个查询。
var orderTask = ordersRepository.Find(orderId); // Takes 1 second
var invoicesTask = invoiceRepository.FindBy(orderId); // Takes 2 seconds
var deliveriesTask = deliveryRepository.FindBy(orderId); // Takes 3 seconds
await Task.WhenAll(orderTask, invoicesTask, deliveriesTask);
var order = await orderTask;
var invoices = await invoicesTask;
var deliveries = await deliveriesTask;
如果将一一执行,三个查询将在 3 秒内完成,而不是 6 秒。
单个 DbContext 不支持同时异步调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.