带有 EF Core 的 .NET 项目在一个特定页面上引发 ObjectDisposedException
Posted
技术标签:
【中文标题】带有 EF Core 的 .NET 项目在一个特定页面上引发 ObjectDisposedException【英文标题】:.NET project with EF Core throws ObjectDisposedException on one particular page 【发布时间】:2022-01-07 12:10:13 【问题描述】:当我尝试访问页面时,带有 Entity Framework 的 ASP.NET Core 项目出错。我尝试用谷歌搜索错误,我的方法是使用async Task
而不是 void,我在AddDbContextPool
上设置了sqlOptions.EnableRetryOnFailure();
。但是当我们访问该页面时,它仍然会出错
ObjectDisposedException:无法访问已释放的上下文实例。此错误的一个常见原因是释放从依赖注入中解析的上下文实例,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您在上下文实例上调用“Dispose”或将其包装在 using 语句中,则可能会发生这种情况。如果你使用依赖注入,你应该让依赖注入容器负责处理上下文实例。
在我正在缓存的页面的Index()
上
public class CustomersController : Controller
private readonly SurplusMouseContext _context;
private readonly IMemoryCache memoryCache;
public CustomersController(SurplusMouseContext context, IMemoryCache _memoryCache)
_context = context;
memoryCache = _memoryCache;
// GET: Customers
public async Task<IActionResult> Index(string sortOrder, string searchString,
int? pageNumber, string currentFilter)
var timeUtc = DateTime.UtcNow;
IQueryable<JAXSurplusMouseApp.Models.Setting> settings_data = null;
IQueryable<JAXSurplusMouseApp.Models.HolidayWeek> holidaycheck = null;
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var todayDt = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, easternZone);
TimeSpan timeNow = TimeSpan.Parse(todayDt.ToString("HH:mm:ss"));
bool isExist = memoryCache.TryGetValue("HolidayWk", out holidaycheck);
if (!isExist)
holidaycheck = (from hc in _context.HolidayWeeks
where hc.HolidateDate == todayDt.Date
select hc);
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromHours(2));
memoryCache.Set("HolidayWk", holidaycheck, cacheEntryOptions);
bool isSettingExist = memoryCache.TryGetValue("SMSettings", out settings_data);
if (!isSettingExist)
settings_data = (from s in _context.Settings
select s).Take(1);
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromHours(2));
memoryCache.Set("SMSettings", settings_data, cacheEntryOptions);
int i = settings_data.Count();
if (holidaycheck.Count() != 0)
HolidayWeek viewmodel = new HolidayWeek
Holiday = holidaycheck.First().Holiday.ToUpper()
;
return View("/Views/Customers/AppNotAvailableHoliday.cshtml", viewmodel);
else if (settings_data.Count() != 0)
string myCondition = (todayDt.DayOfWeek.ToString().Substring(0, 3)).ToUpper();
string abc = settings_data.First().OrderDay;
TimeSpan start = TimeSpan.Parse(settings_data.First().StartTime);
TimeSpan end = TimeSpan.Parse(settings_data.First().EndTime);
bool checktime = (timeNow >= start) && (timeNow <= end);
if ((settings_data.First().OrderDay == myCondition)&&((timeNow>=start) && (timeNow <= end)))
ViewData["CustomerParam"] = String.IsNullOrEmpty(sortOrder) ? "customer_desc" : "";
ViewData["LocationParam"] = String.IsNullOrEmpty(sortOrder) || sortOrder == "location_asc" ? "location_desc" : "location_asc";
ViewData["CurrentFilter"] = searchString;
ViewData["CurrentSort"] = sortOrder;
if (searchString != null)
pageNumber = 1;
else
searchString = currentFilter;
var cust = from s in _context.Customers
select s;
if (!String.IsNullOrEmpty(searchString))
cust = cust.Where(s => s.Location.Contains(searchString));
switch (sortOrder)
case "location_desc":
cust = cust.OrderByDescending(s => s.Location);
break;
case "location_asc":
cust = cust.OrderBy(s => s.Location);
break;
case "customer_desc":
cust = cust.OrderBy(s => s.CustomerNumber);
break;
default:
cust = cust.OrderBy(s => s.Location);
break;
int pageSize = 15;
return View(await PaginatedList<Customer>.CreateAsync(cust.AsNoTracking(), pageNumber ?? 1, pageSize));
else
Setting ss = new Setting
OrderDay = settings_data.First().OrderDay,
StartTime = settings_data.First().StartTime,
EndTime = settings_data.First().EndTime
;
return View("/Views/Customers/AppNotAvailableSettings.cshtml", ss);
return View("/Views/Customers/AppNotAvailableSettings.cshtml");
我正在查询两个不同的表 HolidayWeek
和 Setting
以检查客户页面是否可用。如果无法访问客户页面,我会向用户返回不同的视图。我不确定我是否缺少缓存部分的任何内容。
这个错误一出现就非常不一致,然后又失败了。任何人都可以建议我是否在这里遗漏了什么?
【问题讨论】:
【参考方案1】:您正在尝试缓存IQueryable
,这是查询的延迟执行。它包含对DbContext
的引用,稍后由容器处理。
所以解析很简单——在缓存之前实现对象:
memoryCache.Set("HolidayWk", await holidaycheck.ToListAsync(), cacheEntryOptions);
其他地方也有同样的错误。
无论如何,您可能必须更改缓存条目的类型:
public async Task<IActionResult> Index(string sortOrder, string searchString,
int? pageNumber, string currentFilter)
var timeUtc = DateTime.UtcNow;
List<JAXSurplusMouseApp.Models.Setting> settings_data = null;
List<JAXSurplusMouseApp.Models.HolidayWeek> holidaycheck = null;
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var todayDt = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, easternZone);
TimeSpan timeNow = TimeSpan.Parse(todayDt.ToString("HH:mm:ss"));
bool isExist = memoryCache.TryGetValue("HolidayWk", out holidaycheck);
if (!isExist)
holidaycheck = await (from hc in _context.HolidayWeeks
where hc.HolidateDate == todayDt.Date
select hc).ToListAsync();
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromHours(2));
memoryCache.Set("HolidayWk", holidaycheck, cacheEntryOptions);
bool isSettingExist = memoryCache.TryGetValue("SMSettings", out settings_data);
if (!isSettingExist)
settings_data = await (from s in _context.Settings
select s).Take(1).ToListAsync();
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromHours(2));
memoryCache.Set("SMSettings", settings_data, cacheEntryOptions);
...
【讨论】:
你能帮我解决我遇到的其他错误吗settings_data
也缓存为IQueryable
但我无法更改 await holidaycheck.ToListAsync()
它会抛出错误 'IQueryable<HolidayWeek>' does not contain a definition for 'ToListAsync' and no accessible extension method 'ToListAsync' accepting a first argument of type 'IQueryable<HolidayWeek>' could be found (are you missing a using directive or an assembly reference?)
怎么可能?这是广泛使用的 EF Core 扩展。可能你必须添加using Microsoft.EntityFrameworkCore;
我已经有了using Microsoft.EntityFrameworkCore;
我可以保留IQueryable<JAXSurplusMouseApp.Models.HolidayWeek> holidaycheck = null;
原样吗?以上是关于带有 EF Core 的 .NET 项目在一个特定页面上引发 ObjectDisposedException的主要内容,如果未能解决你的问题,请参考以下文章
带有 EF Core 的 ASP.NET Core - DTO 集合映射
带有 EF Core / ASP.NET Core 的 OData - 好还是坏?
带有 EF Core 和 CosmosDB .NET 5 的 ASP.Net Core - IdentityRole 问题
带有 UWP 的 EF Core - Visual Studio 19