0

我正在尝试使用 fastcrud 制作 UnitOfWork/Repository 模式。

我创建了一个通用存储库

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是一个委托的Action,我做不到

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.
4

2 回答 2

0

你可以这样做:

public IEnumerable<T> Find(Action<IRangedBatchSelectSqlSqlStatementOptionsOptionsBuilder<T>> statementOptions = null)
{
     statementOptions += s => s.AttachToTransaction(this.Transaction);
     return Connection.Find<T>(statementOptions);
}
于 2019-05-09T19:24:00.440 回答
0

我也有同样的问题。我用这个扩展方法解决了它:

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));
}
于 2019-12-26T14:29:36.900 回答