使用相同的数据库上下文运行多个选择查询
Posted
技术标签:
【中文标题】使用相同的数据库上下文运行多个选择查询【英文标题】:Running multiple select queries using the same db context 【发布时间】:2019-05-03 03:12:20 【问题描述】:您能否使用相同的数据上下文运行多个“选择”查询?今天在工作中,我遇到了使用Entity Framework 4在同一上下文中运行多个“选择”查询时查询返回不准确结果的情况。代码类似于下面的代码:
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 之前的结果。我怀疑这是因为直到这个 using 块结束时才会处理上下文。我想知道将来是否为了避免这个错误,我应该在每次查询后处理上下文。
【问题讨论】:
【参考方案1】:DataContext 的更改跟踪器会累积您在 DataContext 的生命周期内获取的所有实体。变更跟踪器将“修复”在单独查询中获取的实体之间的关系。因此,在检查导航属性时,您可能会看到先前查询的结果。
但这不会影响您发布的代码。此外,您应该使用 EF 6,而不是 EF 4。
【讨论】:
【参考方案2】:DbContext 会记住您已经获取的项目。这是在您保存之前能够更改获取的数据所必需的。
示例: 假设你有一所学校,有很多老师和很多学生;每个老师有零个或多个学生,每个学生有零个或多个老师(多对多关系)
假设学生 [100] 名叫 Theresa,住在“伦敦唐宁街 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();
问题:Theresa 应该在伦敦学生群体中,还是在牛津学生群体中?
实体框架的设计者认为这是明智的,一旦您获取了 TheresaMay 并更改了一个属性,对于您来说,该属性的值将是新值,而不是仍在数据库中的值。
因为我们不知道您是否成功保存了更改,其他将获取 TheresaMay 的人仍然会获取数据库值。
因此,保持上下文打开以查询多个项目有点危险,因为如果其他人更改了您已经获取的项目之一,您将看不到这些更改。因此,明智的做法是只在您真正需要的时候保留您的 dbContext。通常这大约是您通常锁定数据库的时间或您保持事务活跃的时间。
【讨论】:
以上是关于使用相同的数据库上下文运行多个选择查询的主要内容,如果未能解决你的问题,请参考以下文章
React:如何使用相同类型的多个上下文,同时允许孩子从所有上下文中读取数据