通过 Azure 函数注入 DbContext 时无法访问已处置的对象
Posted
技术标签:
【中文标题】通过 Azure 函数注入 DbContext 时无法访问已处置的对象【英文标题】:Cannot access a disposed object when injecting DbContext through Azure Function 【发布时间】:2019-11-20 01:22:08 【问题描述】:我在尝试将 DbContext 注入 Azure 函数时收到以下错误:
Microsoft.EntityFrameworkCore: Cannot access a disposed object.
这是当前函数
private readonly FundCentreContext _fundCentreContext;
public GetDailyPrices(FundCentreContext fundCentreContext)
_fundCentreContext = fundCentreContext;
[Produces("application/json")]
[FunctionName(nameof(GetDailyPrices))]
public IActionResult Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "api/dailyprices")] HttpRequest req,
ILogger log)
//Parameters
var parameters = req.GetQueryParameterDictionary();
var page = int.Parse(parameters.GetValueOrDefault("page", "0"));
var limit = int.Parse(parameters.GetValueOrDefault("limit", "10"));
var offset = int.Parse(parameters.GetValueOrDefault("offset", "0"));
var sort = parameters.GetValueOrDefault("sort", "asc");
var fundService = new FundService(_fundCentreContext);
var fundDailyPrices = fundService.GetAllDailyPricesByPage(page, limit, offset);
return fundDailyPrices != null
? (ActionResult)new OkObjectResult(fundDailyPrices)
: new BadRequestObjectResult("There was an error with your request");
并且使用该服务的启动有以下代码:
services
.AddDbContext<FundCentreContext>(options =>
options.UseSqlServer("*ommited*"));
我不知道为什么会发生这个错误 - 调试过去的 return 语句有效,并且可以在 fundDailyPrices 对象中看到数据,但是 return 语句之后的某些东西意外地结束了整个函数。
【问题讨论】:
你的GetAllDailyPricesByPage
函数是async
吗?
如果没有任何等待,为什么要使用async Task
?
我打算将 await 添加到 GetAllDailyPricesByPage() 函数,但目前它无论如何都不是异步的。我编辑了问题并删除了异步以消除混乱。使用同步函数仍然会发生错误。
这可能会有所帮助 - ***.com/questions/65242457/…
【参考方案1】:
很难用您提供的代码来判断,但最可能的罪魁祸首是在上下文超出范围之前您没有具体化结果集。同样,我们看不到所有代码,但是当您执行诸如直接返回 IQueryable
之类的操作时会发生这种情况。任何类型的服务调用都应该返回一个具体化列表(即在返回之前对结果集调用ToList()
或ToListAsync()
)。如果您启用了该功能,它也可能是由延迟加载引起的。如果是这样,你应该确保所有必要的关系都被急切地加载。
使用注入上下文来更新服务也很奇怪。你应该简单地注入你的服务,因为它对你的上下文有一个构造函数依赖,它将被自动注入它。这可确保两个对象在相同的或至少兼容的生命周期内运行。
另外,不要将IDisposable
与注入的依赖项一起使用。我们无法提供有关您的服务类的任何信息,但如果它确实实现了IDisposable
,请将其删除。
【讨论】:
用 EF 注入 DbContext 不是很标准吗?我不确定你为什么不注射一次性的东西。 你把不同的东西混为一谈。这里的问题不是注入服务,而不是上下文。当然应该注入上下文,但是当使用 DI 时,应该注入链上和下的所有内容。第二个问题是在服务类上实现 IDisposable,假设它不拥有任何依赖项。上下文被注入,所以服务类绝对不应该释放上下文,因为它不拥有它。以上是关于通过 Azure 函数注入 DbContext 时无法访问已处置的对象的主要内容,如果未能解决你的问题,请参考以下文章
注入 dbContext 时返回“找不到与给定参数匹配的构造函数”
使用 DBContext 将 SQL Server 数据库与时间触发的 Azure 函数连接起来
使用 Azure Function 2.x 通过构造函数为 Http 触发函数注入 ILogger