如何解决在此LINQ查询中销毁后,为什么要使用数据库上下文?
我有以下查询和EF Core 2.2.6
public async Task<List<SamplePointContamination>> GetSamplePointsContaminationAsync(int siteId,int buildingId)
{
var siteZones = await administrationApiClient.GetAsync<List<BuildingZone>>($"sites/{siteId}/buildingZones",new List<KeyValuePair<string,string>>() { new KeyValuePair<string,string>("IncludeBuildings","True") });
var buildingZoneIds = siteZones.Where(x => x.Building.Id == buildingId).Select(x => x.Id);
if (!buildingZoneIds.Any())
throw new SecurityException("Building does not belong to the site.");
var timeFrom = DateTimeOffset.UtcNow.AddDays(-9);
using (var dbContext = CreateDbContext())
{
//TODO optimize query. Generated sql does not promise
return await dbContext.Analyses
.Where(x => buildingZoneIds.Contains(x.Sample.SamplePoint.BuildingZoneId) && x.CreatedAt >= timeFrom
&& x.Sample.SamplePoint.Top.HasValue && x.Sample.SamplePoint.Left.HasValue)
.Include(x => x.Sample.SamplePoint)
.Include(x => x.AnalysisRisks)
.ThenInclude(x => x.Risk)
.GroupBy(x => new
{
x.Sample.SamplePoint.Id,x.Sample.SamplePoint.Name,x.Sample.SamplePoint.Top,x.Sample.SamplePoint.Left
})
.Select(x => new SamplePointContamination()
{
Id = x.Key.Id,Name = x.Key.Name,Top = x.Key.Top.Value,Left = x.Key.Left.Value,WaitingResults = x.Count(y => !y.ResultPositive.HasValue),RiskTypes = x.SelectMany(y => y.AnalysisRisks)
.GroupBy(y => new { Id = (int)y.Risk.RiskType,Name = y.Risk.RiskType.ToString() })
.Select(y => new RiskTypeContamination()
{
Id = y.Key.Id,Name = y.Key.Name,Positives = y.Count(z => z.Analysis.ResultPositive == true),Negatives = y.Count(z => z.Analysis.ResultPositive == false),IsPositive = y.Any(z => z.Analysis.ResultPositive == true)
}).ToList() //Crashes if ToList() is omitted. If using statement is removed,ToList() is not needed
})
.ToListAsync();
}
}
第一个问题是,底层的SQL查询效率很低,因为除非在大多数简单情况下,否则GROUP BY几乎从未应用于数据库(而是在内存中完成),但这不是主题。
主题是,由于某些原因,如果省略ToList()(在代码末尾的第5行有注释),应用程序将崩溃。另外,如果我删除using语句,也没有错误。我所有的查询在使用时都使用这种模式,直到现在我再也没有遇到任何问题。我知道我不必使用using,但是根据我的意见,如果以这种方式使用,它应该不会出现问题,因为我从不尝试在此范围之外访问dbContext实例。显示此错误:
Microsoft.EntityFrameworkCore:无法访问已处置的对象。一种 导致此错误的常见原因是处理已解决的上下文 从依赖注入,然后稍后尝试使用相同的 应用程序中其他位置的上下文实例。这可能是你 在上下文上调用Dispose()或将上下文包装在 使用语句。如果使用依赖项注入,则应让 依赖项注入容器负责处理上下文 实例。对象名称:“上下文”。
因此,显然在销毁之后再次使用了dbContext,但是我没有在代码中明确地这样做。显然,它与async / await有某种联系,由于某些原因,添加提到的ToList()可以解决此问题,但是我不知道发生了什么以及为什么没有它就存在错误。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。