Я использую транзакции в своих модульных тестах для отката изменений. unit test использует dbcontext, а служба, которую я тестирую, использует свою. Оба они завернуты в одну транзакцию, а один dbcontext находится в блоке другого. Дело в том, что когда внутренний dbcontext сохраняет свои изменения, он не виден внешнему dbcontext (и я не думаю, потому что в другом dbcontext уже может быть загружен объект). Вот пример:
[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 для assert, все работает нормально:
[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) похоже на транзакцию? Если это так, я все еще не понимаю проблему, так как я вызываю .SaveChanges() во внутреннем dbcontext.