繁体   English   中英

DB上下文-多种用法

[英]Db context - multiple usages

所以我偶然发现了一件奇怪的事情。 我有一个将workingsiteuntil日期更改为昨天的测试,如下所示:

using (var db = new ApplicationDbContext())
        {
            var empFromDb = db.Employees.Include(x => x.WorkingSites).First(x => x.Id == _employeeId);
            empFromDb.WorkingSites.Add(workingSiteToEnd);
            db.SaveChanges();

        //Act
        ServiceFactory.CreateEmployeeService().EndWorkingSitePeriod(workingSiteToEnd);

        //Assert
            var workingSiteFromDb = db.WorkingSites.First(x => x.Id == workingSiteToEnd.Id);

            Assert.AreEqual(DateTime.Now.AddDays(-1).Date, workingSiteFromDb.WorksUntil.Date);
        }

在此测试中,我的断言失败,并且对对象workingSiteFromDbuntil未更改,但是在我的代码中,我确实对其进行了更改并将更改保存到数据库。 注意 :我的数据库没有更新! 我检查了数据库内部,日期正确更改。

现在我不知道发生了什么,因此我在第一次savechanges后立即停止using ,并在调用workingSiteFromDb之前再次将其workingSiteFromDb

如果我这样做,它会起作用。

请注意,我用另一个using的内EndWorkingSitePeriod方法。

为什么我的数据库会更新,而对象仅在使用第二个using时才会更新?

这是EndWorkingSitePeriod方法:

public void EndWorkingSitePeriod(int workingSiteId)
    {
        using (var db = new ApplicationDbContext())
        {
            var workingSiteFromDb = db.WorkingSites.Include(x => x.Employee).First(x => x.Id == workingSiteId);
            workingSiteFromDb.EndPeriod();
            db.SaveChanges();
        }
    }

workingSite.EndPeriod只是将UntilDate DateTime.Now.AddDays(-1)设置为DateTime.Now.AddDays(-1)

首先,您将在某个地方获得workingSiteToEnd并将其添加到在示例的第一行中创建的上下文中。 然后,您要保存更改(现在在数据库上下文中保存workingSiteToEnd )。

然后,您将在EndWorkingSitePeriod方法中创建第二个上下文。 使用该上下文,您将获得新的 workingSiteFromDb实例(与上面的workingSiteToEnd不相关)。 您正在修改它,并保存更改。

现在,您正在尝试测试所做的更改,但是原始的 workingSiteToEnd仍然存在于上下文中。 这意味着,当您尝试再次从数据库中加载它时,上下文在实现过程中将在其本地缓存中查找具有相同键的实体,将找到它,并返回现有的原始实体,不变的workingSiteToEnd (您可以比较引用,它们将是相等的)。

当您在第一次SaveChanges之后立即关闭using块,然后创建新的块时,您正在创建新的上下文,该上下文将为workingSiteFromDb加载新实例,并且测试将通过。

不要嵌套使用同一DbContext。 相反,如果您需要在调用的方法中使用相同的上下文,则将其与参数一起传递,例如:

using (var db = new ApplicationDbContext())
{
   var empFromDb = db.Employees.Include(x => x.WorkingSites).First(x => x.Id == _employeeId);
   empFromDb.WorkingSites.Add(workingSiteToEnd);
   db.SaveChanges();

   //Act
   ServiceFactory.CreateEmployeeService().EndWorkingSitePeriod(workingSiteToEnd, db);

   //Assert
   var workingSiteFromDb = db.WorkingSites.First(x => x.Id == workingSiteToEnd.Id);

   Assert.AreEqual(DateTime.Now.AddDays(-1).Date, workingSiteFromDb.WorksUntil.Date);
}

private void EndWorkingSitePeriod(int workingSiteId, ApplicationDbContext db)
{
    var workingSiteFromDb = db.WorkingSites.Include(x => x.Employee).First(x => x.Id == workingSiteId);
    workingSiteFromDb.EndPeriod();
    db.SaveChanges();
}

// if you need it public, then use this too
public void EndWorkingSitePeriod(int workingSiteId)
{
    using (var db = new ApplicationDbContext()) 
    {
       EndWorkingSitePeriod(workingSiteId, db);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM