我正在编写集成测试,我想使用事务范围。 我们使用EF和存储库与上下文。
如果我有一个Repository和一个Context,那么它看起来像这样:
[TestInitialize]
public void RuleEngineTestsStart() {
customContext = new CustomContext();
transaction = customContext.Database.BeginTransaction();
repo = new CustomRepository(customContext);
// I need to make this context to work in the same transaction as above
anotherContext = new AnotherContext();
anotherRepo = new AnotherRepository(anotherContext);
}
在测试结束时(TestCleanup
)我想transaction.Rollback();
一切。
我希望所有使用不同上下文的存储库拥有相同的事务,是否可能?如何创建事务并将其“发送”到所有三个上下文? 请不要对所有存储库使用一个上下文,但由于原因(我们希望以后每个上下文都有自己的DbSets在微服务中使用),这是不可能的。
修改 在评论中我被要求包含更多代码,但是,我认为没有必要回答我的问题。
customContext = new CustomContext();
repo = new CustomRepository(customContext);
customContext2 = new CustomContext2();
otherRepository = new CustomRepository2(customContext2);
// class to be tested needs both repositories
ToBeTestedClass cl = new ToBeTestedClass(customRepository, otherRepository);
// "BASE" interface
public interface IRepository<TEntity> where TEntity : class
{
TEntity GetById(long id);
IEnumerable<TEntity> GetByFilter(Expression<Func<TEntity, bool>> predicate);
TEntity GetSingleByFilter(Expression<Func<TEntity, bool>> filter);
void Insert(TEntity entity);
void Delete(long id);
void Update(TEntity entity);
...
}
// BASE CLASS
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly DbContext _context;
protected readonly DbSet<TEntity> _dbSet;
public Repository(ColldeskDbContext context)
{
_context = context;
_dbSet = context.Set<TEntity>();
}
// GetSingle, GetAll, Insert, Update etc.
}
// CustomRepository (other Repositories are similar, with custom methods)
public interface ICustomRepository : IRepository<CusotmData>
{
// some specific methods that are not in Base class
}
public class CustomRepository: Repository<CustomData>, ICustomRepository
{
public CustomRepository(CustomContext context) : base(context)
{
}
// custom methods that are specific for given context
}
// Contexts - each context consists of its one DbSets
答案 0 :(得分:0)
请勿在您的存储库中使用dbContext.SaveChanges()
。创建存储库时使用ONE dbContext。样品:
using ( var db = new YourDbContext() )
{
// Create and begin transaction
using ( var transaction = db.Database.BeginTransaction() )
{
try
{
// ONE dbContext for all repositories
var firstRepo = new Custom1Repository(db);
var secondRepo = new Custom2Repository(db);
City city = new City { Description = "My city" };
Street street = new Street { Description = "My street", City = city};
firstRepo.Insert(city);
secondRepo.Insert(street);
// Save all your changes and after that commit transaction
db.SaveChanges();
transaction.Commit();
}
catch ( Exception ec)
{
transaction.Rollback();
}
}
}
这样做你的存储库就变成了DbSet<TEntity>
答案 1 :(得分:0)
我已经发现我可以像这样简单地使用TransactionScope:
private TransactionScope _scope;
[TestInitialize]
public void TestInitialize()
{
_scope = new TransactionScope();
}
[TestCleanup]
public void TestCleanup()
{
_scope.Dispose();
}
然后每个Context都将在此TransactionScope中运行。