是否可以使用相同的数据上下文运行多个"select"查询?今天在工作中,我遇到了这样一种情况:当我使用EntityFramework4在同一上下文中运行多个"select"查询时,查询返回不准确的结果。代码类似于下面的代码:
using(var dataContext = new VisitorDataContext())
{
var v1 = dataContext.Visitor.Where(p => p.VisitorId == 73).FirstOrDefault();
//process v1
var v2 = dataContext.Visitor.Where(p => p.VisitorId == 98).FirstOrDefault();
//process v2
var v3 = dataContext.Visitor.Where(p => p.VisitorId == 100).FirstOrDefault();
//provess v2
}
所以发生在我身上的是v2包含了v1之前的结果。我怀疑这是因为上下文直到这个使用块结束才被处理。我想知道将来,为了避免这个错误,我是否应该在每次查询后处理上下文。
DataContext的Change Tracker在DataContext的生存期内累积您获取的所有实体。更改跟踪器将"修复"在单独查询中提取的实体之间的关系。因此,在检查导航属性时,您可能会看到以前查询的结果。
但这不会影响你发布的代码。此外,你应该使用EF 6,而不是EF 4。
DbContext会记住您已经提取的项目。这是需要能够在保存之前更改提取的数据。
示例:假设你有一所学校,有很多老师和学生;每个教师有零个或多个学生,每个学生有零个或者多个教师(多对多关系(
假设学生[100]名叫特蕾莎,住在"伦敦唐宁街10号",她搬家了。同时,你想通知住在附近的所有其他学生她的新地址:
var TheresaMay = dbContext.Students.
.Where(student => student.Id == 100)
.FirstOrDefault();
// change address of TheresaMay:
theresaMay.Address = "King's College, Oxford",
数据还没有保存,在数据库中她仍然住在伦敦。如果您要使用这个值,您想要什么?更改后的值或数据库值:
var city = theresaMay.City; // London or Oxford?
通知附近的所有学生她的新地址
var nearbyStudents = dbContext.Students
.Where(student => student.City == theresaMay.City)
.ToList();
SendMessage(nearbyStudents)
你想让牛津的学生收到通知,还是想让伦敦的学生收到?
假设你想招收按城市分组的学生:
var studentsGroupedByCitry = dbContext.Students
.GroupBy(student => student.City)
.ToList();
问题:特蕾莎应该加入伦敦学生组,还是牛津学生组?
实体框架的设计者认为,一旦你获取了TheresaMay并更改了一个属性,对你来说,这个属性的值将是新的值,而不是仍在数据库中的值。
因为我们不知道您是否成功保存了更改,所以其他将获取TheresaMay的人仍然会获得数据库值。
因此,保持上下文打开以查询多个项目有点危险,因为如果其他人更改了您已经提取的项目之一,您将看不到这些更改。因此,明智的做法是只在您真正需要的时间内保留dbContext。通常,这大约是您通常锁定数据库的时间,或者是您保持事务活动的时间。