Добавить AttachToTransaction к действию в FastCrud
Я пытаюсь сделать шаблон UnitOfWork/Repository, используя fastcrud.
Я создал общий репозиторий
public interface IRepository<T> where T : BaseEntity
{
IDbTransaction Transaction { get; set; }
T Get(T entityKeys, Action<ISelectSqlSqlStatementOptionsBuilder<T>> statementOptions = null);
IEnumerable<T> Find(Action<IRangedBatchSelectSqlSqlStatementOptionsOptionsBuilder<T>> statementOptions = null);
int Count(Action<IConditionalSqlStatementOptionsBuilder<T>> statementOptions = null);
bool Delete(T entityToDelete, Action<IStandardSqlStatementOptionsBuilder<T>> statementOptions = null);
}
Из службы звоню
var repo = UnitOfWork.GetRepository<MyTable>();
var myList = repo.Find(statement => statement
.AttachToTransaction(repo.Transaction)
.OrderBy($"{nameof(MyTable.Name):C}")
);
Это работает. Но я не хочу, чтобы сервис обрабатывал вызов AttachToTransaction, вместо этого я хотел бы добавить его в свой репозиторий.
public IEnumerable<T> Find(Action<IRangedBatchSelectSqlSqlStatementOptionsOptionsBuilder<T>> statementOptions = null)
{
return Connection.Find<T>(statementOptions);
}
Но здесь StatementOption является делегированным действием, и я не могу сделать
statementOption.AttachToTransaction(this.Transaction)
Мой UnitOfWork всегда создает транзакцию, поэтому, если я пропущу присоединение к транзакции, я получу исключение
An unhandled exception occurred while processing the request.
InvalidOperationException: ExecuteReader requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.
0 ответов
Сделать это можно так:
public IEnumerable<T> Find(Action<IRangedBatchSelectSqlSqlStatementOptionsOptionsBuilder<T>> statementOptions = null)
{
statementOptions += s => s.AttachToTransaction(this.Transaction);
return Connection.Find<T>(statementOptions);
}
У меня тоже была такая же проблема. Я использовал этот метод расширения, чтобы решить эту проблему:
internal static IRangedBatchSelectSqlSqlStatementOptionsOptionsBuilder<TEntity> AttachToTransaction<TEntity>(
this IRangedBatchSelectSqlSqlStatementOptionsOptionsBuilder<TEntity> statement,
Action<IRangedBatchSelectSqlSqlStatementOptionsOptionsBuilder<TEntity>> originalStatementOptionsBuilder,
IDbTransaction transaction)
{
if (originalStatementOptionsBuilder == null)
{
statement.AttachToTransaction(transaction);
}
else
{
originalStatementOptionsBuilder(statement);
statement.AttachToTransaction(transaction);
}
return statement;
}
Теперь ваша служба должна измениться так:
public IEnumerable<T> Find(Action<IRangedBatchSelectSqlSqlStatementOptionsOptionsBuilder<T>> statementOptions = null)
{
return Connection.Find<T>(s => s.AttachToTransaction(statementOptions, this.Transaction));
}