[英]Db context - multiple usages
所以我偶然发现了一件奇怪的事情。 我有一个将workingsite
的until
日期更改为昨天的测试,如下所示:
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);
}
在此测试中,我的断言失败,并且对对象workingSiteFromDb
的until
未更改,但是在我的代码中,我确实对其进行了更改并将更改保存到数据库。 注意 :我的数据库没有更新! 我检查了数据库内部,日期正确更改。
现在我不知道发生了什么,因此我在第一次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.