所以我刚才偶然发现了一件奇怪的事情。
我有一个测试会将until
的{{1}}日期更改为昨天,如此:
workingsite
在此测试中,我的断言失败,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);
}
没有为对象until
更改,但在我的代码中,我确实更改了它并将更改保存到数据库中。
注意:我的数据库已更新!我检查了数据库内部并正确更改了日期。
现在我还不知道发生了什么,所以我在第一个workingSiteFromDb
之后立即停止using
,并在我致电savechanges
之前再次打开它。
如果我这样做,它就有效。
请注意,我在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
答案 0 :(得分:2)
首先,您在某处获得workingSiteToEnd
并将其添加到您在样本第一行中创建的上下文中。然后,您将保存更改(workingSiteToEnd
现在在数据库中和在上下文中。)
然后,您在EndWorkingSitePeriod
方法中创建第二个上下文。使用该上下文,您即可获得新 workingSiteFromDb
实例(它与上面的workingSiteToEnd
无关)。您正在修改它并保存更改。
现在,您正在尝试测试您所做的更改,但原始 workingSiteToEnd
仍然存在于上下文中。这意味着,当您再次尝试从数据库加载它时,在实现过程中,上下文将在其本地缓存中查找具有相同密钥的实体,将找到它,并将返回现有实体,即原始,未更改workingSiteToEnd
(您可以比较引用,它们相等)。
如果您在第一次using
之后立即关闭SaveChanges
阻止,然后再创建新的,则会创建新上下文,这将加载workingSiteFromDb
的新实例,测试将通过。
答案 1 :(得分:0)
不要嵌套相同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);
}
}