【问题标题】: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 块结束时才会处理上下文。我想知道将来是否为了避免这个错误,我应该在每次查询后处理上下文。

【问题讨论】:

    标签: asp.net-mvc entity-framework entity-framework-4


    【解决方案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。通常这大约是您通常锁定数据库的时间或您保持事务活跃的时间。

      【讨论】:

        猜你喜欢
        • 2023-04-04
        • 2013-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-24
        • 2013-09-07
        • 1970-01-01
        • 2014-08-15
        相关资源
        最近更新 更多