我在單元測試中使用事務來回滾更改。單元測試使用了一個dbcontext,並且我正在測試的服務使用他自己的。它們都被封裝在一個事務中,並且一個dbcontext在另一個事務的塊中。問題是,當內部dbcontext保存其更改時,它對外部dbcontext不可見(並且我不認爲這是因爲其他dbcontext可能已經加載了該對象)。這裏是例子:一個事務與多個dbcontexts
[TestMethod]
public void EditDepartmentTest()
{
using (TransactionScope transaction = new TransactionScope())
{
using (MyDbContext db = new MyDbContext())
{
//Arrange
int departmentId = (from d in db.Departments
where d.Name == "Dep1"
select d.Id).Single();
string newName = "newName",
newCode = "newCode";
//Act
IDepartmentService service = new DepartmentService();
service.EditDepartment(departmentId, newName, newCode);
//Assert
Department department = db.Departments.Find(departmentId);
Assert.AreEqual(newName, department.Name,"Unexpected department name!");
//Exception is thrown because department.Name is "Dep1" instead of "newName"
Assert.AreEqual(newCode, department.Code, "Unexpected department code!");
}
}
}
服務:
public class DepartmentService : IDepartmentService
{
public void EditDepartment(int DepartmentId, string Name, string Code)
{
using (MyDbContext db = new MyDbContext())
{
Department department = db.Departments.Find(DepartmentId);
department.Name = Name;
department.Code = Code;
db.SaveChanges();
}
}
}
但是,如果我調用服務之前關閉外的DbContext並打開一個新的DbContext的斷言,一切工作正常:
[TestMethod]
public void EditDepartmentTest()
{
using (TransactionScope transaction = new TransactionScope())
{
int departmentId=0;
string newName = "newName",
newCode = "newCode";
using (MyDbContext db = new MyDbContext())
{
//Arrange
departmentId = (from d in db.Departments
where d.Name == "Dep1"
select d.Id).Single();
}
//Act
IDepartmentService service = new DepartmentService();
service.EditDepartment(departmentId, newName, newCode);
using (MyDbContext db = new MyDbContext())
{
//Assert
Department department = db.Departments.Find(departmentId);
Assert.AreEqual(newName, department.Name,"Unexpected department name!");
Assert.AreEqual(newCode, department.Code, "Unexpected department code!");
}
}
}
所以基本上我有這個問題的解決方案(在寫這個問題時想到它),但我仍然想知道爲什麼它不可能訪問事務中的未提交數據當dbcontexts嵌套時。 難道這是因爲使用(dbcontext)就像事務本身?如果是這樣,我仍然不明白這個問題,因爲我調用內部dbcontext上的.SaveChanges()。
即使使用相同的連接字符串,您也可以擁有分佈式事務。它們將比跨服務器連接更輕量級,但仍然是分佈式的。這種影響是非確定性的,因此非常危險。在測試過程中,你通常很幸運。 OP是幸運的。所以雖然這個答案被接受並且被高度投票,但在這個特殊方面仍然是不正確的。 – usr
@usr你能提供一個我可以查看的鏈接,以改善答案嗎?隨意編輯它自己 – jnovo
這個問題很難找到,但有關於它的「官方」微軟博客,我已經展示了它。我手邊沒有鏈接。 – usr