使用相同的数据库上下文运行多个选择查询



是否可以使用相同的数据上下文运行多个"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。通常,这大约是您通常锁定数据库的时间,或者是您保持事务活动的时间。

最新更新