Теперь я столкнулся с ситуацией, когда мне пришлось обернуть вызовы нескольких репозиториев/функций в другую транзакцию, но когда одна из этих функций уже использует транзакцию внутри себя, я получу ошибку. Соединение уже находится в транзакции и не может участвовать. в другой транзакции.
Я не хочу удалять транзакцию из функции репозитория, поскольку это означало бы, что мне нужно знать, для каких функций репозитория требуется транзакция, которую мне затем придется реализовать на уровне сервиса. С другой стороны, кажется, что я не могу использовать функции репозитория в транзакции, когда они уже используют транзакцию внутри себя. Вот пример того, где я столкнулся с этой проблемой:
Код: Выделить всё
// Reverse engineered classes
public partial class TblProject
{
public TblProject()
{
TblProjectStepSequences = new HashSet();
}
public int ProjectId { get; set; }
public virtual ICollection TblProjectStepSequences { get; set; }
}
public partial class TblProjectTranslation
{
public int ProjectId { get; set; }
public string Language { get; set; }
public string ProjectName { get; set; }
public virtual TblProject Project { get; set; }
}
public partial class TblProjectStepSequence
{
public int SequenceId { get; set; }
public int ProjectId { get; set; }
public int StepId { get; set; }
public int SequencePosition { get; set; }
public virtual TblStep Step { get; set; }
public virtual TblProject Project { get; set; }
}
// Creating a project in the ProjectRepository
public async Task CreateProjectAsync(TblProject project, ...)
{
using (var transaction = this.Context.Database.BeginTransaction())
{
await this.Context.TblProjects.AddAsync(project);
await this.Context.SaveChangesAsync();
// Insert translations... (project Id is required for this)
await this.Context.SaveChangesAsync();
transaction.Commit();
return entity.ProjectId;
}
}
// Creating the steps for a project in the StepRepository
public async Task CreateProjectStepsAsync(int projectId, IEnumerable steps)
{
await this.Context.TblProjectStepSequences.AddRangeAsync(steps);
await this.Context.SaveChangesAsync();
return steps.Select(step =>
{
return step.SequenceId;
}
);
}
// Creating a project with its steps in the service layer
public async Task CreateProjectWithStepsAsync(TblProject project, IEnumerable steps)
{
// This is basically a wrapper around Database.BeginTransaction() and IDbContextTransaction
using (Transaction transaction = await transactionService.BeginTransactionAsync())
{
int projectId = await projectRepository.CreateProjectAsync(project);
await stepRepository.CreateProjectStepsAsync(projectId, steps);
return projectId;
}
}
Я знаю, что с технической точки зрения может быть невозможно вложить эти транзакции, но мне все равно нужно решение, которое использует либо внутреннюю транзакцию репозитория, либо внешнюю (если таковая существует), поэтому я не могу случайно забудьте использовать транзакцию для функций репозитория, которым она требуется.
Подробнее здесь: https://stackoverflow.com/questions/709 ... -ef-core-6
Мобильная версия