c# - 在 C# 中以函数式方式处理数据库事务

标签 c# design-patterns functional-programming

我在看这类代码时想知道,如果您从函数式编程 的角度进行处理,是否有任何可以改进的地方?

你不必严格地重新实现我的例子来回答,如果你有涉及交易的不同例子,那就太好了。

using (var unitOfWork = _uowManager.Begin())
{
    _paymentRepository
       .InsertOrUpdate(payment); // Returns payment instance

    // Being executed to get Payment.Id
    _uowManager
       .SaveChanges();

    _otherRepository
       .OtherMethod(payment.Id); // Could be changed as necessary

    unitOfWork
       .Complete()
}

以上代码基于ASP.NET Boilerplate和 Entity Framework (如果有帮助的话)。

最佳答案

我认为创建事务性 monad 是处理这个问题的好方法。不管 C# 中有多少 FP,这都会带来很多好处:

  • 单一、全局、统一的交易处理方式
  • 不要重复自己,写一次这个类并且不要为每个 Controller 函数重新创建事务逻辑n次
  • 您可以创建此类作为接口(interface)并在集成测试中对其进行模拟,例如回滚事务,这样您的测试就不会影响数据库状态

我用的是这样的:

public class Tx
{     
        public DbConnectionExtra _connection { get; set; } // class which has DbTransaction and DbConnection combined 

        public T UseTx<T>(Func<T> fnToCall)
        {          
            try
            {
                _connection.BeginTransaction();

                var result = fnToCall();

               _connection._transaction.Commit();
               _connection._transaction.Dispose();

                return result;
            }
            catch
            {
               _connection._transaction.Rollback();
                _connection._transaction.Dispose();

                throw;
            }
        }
}

关于c# - 在 C# 中以函数式方式处理数据库事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37723450/

相关文章:

functional-programming - 'foldp' 是否违反了 FP 的不可变状态原则?

c# - 如何仅在程序安装后第一次加载表单

c# - SetCursorPos 不工作

java - 为什么 ConcurrentHashMap.Segment 和 ConcurrentHashMap.HashEntry 类是静态的?

java - Spring Framework - 为游戏创建规则引擎的设计模式

c# - 如何为电子邮件消息中的占位符编码?

javascript - 编写可重用的 javascript 模块和库。

c# - 这个事件处理代码会导致内存泄漏吗?

c# - Windows 上 Git 的持续集成

haskell - 有人对函数式编程入门有什么建议吗?