我可以';不要在此处将ADO.NET实体模型实例包装在using语句中
本文关键字:实体模型 NET 实例 包装 语句 using ADO 我可以 | 更新日期: 2023-09-27 18:27:08
我有一个ASP.NET MVC WebAPI项目,我有一条通过ID获得调查的入口点。
public IEnumerable<Models.SurveyQuestionViewModel> GetSurveyById(int id)
{
using (ITSurveyEntities model = new ITSurveyEntities())
{
var questions = model.SurveyQuestions.Where(s => s.SurveyId == id).AsEnumerable();
if (!questions.Any())
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return (from q in questions
select new Models.SurveyQuestionViewModel
{
Id = q.Id,
Question = q.Question,
LongDescription = q.LongDescription,
});
}
}
然而,当我向它提出请求时:
$.getJSON(apiUrl + '/' + id)
.done(function (item) {
surveyBusy.hide();
var o = $('#survey-content');
})
.fail(function (jqXHR, textStatus, err) {
var o = $('.error-bar');
if (err === 'Not Found') {
o.text('The survey you requested doesn''t yet have any questions configured.');
}
else {
o.text('An error occurred: ' + err);
}
o.fadeIn();
});
我陷入了:fail
处理程序。在通过开发工具检查实际响应后,我发现根本原因如下:
操作无法完成,因为DbContext已被释放。
我用错这个物体了吗?我认为一切都很好,因为我正在为初始查询调用AsEnumerable()
,从而提前完成到数据库的往返。当我看到底部的结果时,它没有进行任何数据库调用。我只是将这些值封送至视图模型。
您正在延迟查询。试试这个:
return (from q in questions
select new Models.SurveyQuestionViewModel
{
Id = q.Id,
Question = q.Question,
LongDescription = q.LongDescription,
}).ToList();
快速解决方法是调用ToList()
:
return (from q in questions
select new Models.SurveyQuestionViewModel
{
Id = q.Id,
Question = q.Question,
LongDescription = q.LongDescription,
});
这将使延迟加载短路,并防止错误的发生。
然而,IoC容器可以使用非常适合web的工作单元模式来简化这个问题。当HTTP谓词触发时,您的上下文就会活跃起来,当会话结束时,IoC会处理控制器的处理。不需要using
,也不需要处理这些令人头疼的错误。