Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在事务范围中执行查询的通用方法_C#_Generics_Transactionscope - Fatal编程技术网

C# 在事务范围中执行查询的通用方法

C# 在事务范围中执行查询的通用方法,c#,generics,transactionscope,C#,Generics,Transactionscope,我正在创建一个通用方法,允许我在事务范围内包含数据库的每个操作。目前,我的代码中有多个LINQ到SQL操作,例如: var myVar = MyContext.First(c => c.Id == myId); 我现在拥有的是每个可能操作的通用方法,例如Count、First、FirstOrDefault、ToList等: public static TSource FirstReadUncommitted<TSource>(this IQueryable<TSourc

我正在创建一个通用方法,允许我在事务范围内包含数据库的每个操作。目前,我的代码中有多个LINQ到SQL操作,例如:

var myVar = MyContext.First(c => c.Id == myId);
我现在拥有的是每个可能操作的通用方法,例如Count、First、FirstOrDefault、ToList等:

public static TSource FirstReadUncommitted<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate = null)
    {
        var transactionOptions = new TransactionOptions()
        {
            IsolationLevel = IsolationLevel.ReadUncommitted
        };
        TSource outputItem;
        using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
        {
            outputItem = predicate != null ? source.First(predicate) : source.First();
            scope.Complete();
        }
        return outputItem;
    }
但是,我想要一种更通用的方法,在这种方法中,我可以通过某种方式将我要应用于查询的方法作为参数传递,如下所示:

public static TSource ReadUncommittedFunction<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate = null, Function????? function)
        {
            var transactionOptions = new TransactionOptions()
            {
                IsolationLevel = IsolationLevel.ReadUncommitted
            };
            TSource outputItem;
            using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
            {
                outputItem = predicate != null ? source.function(predicate) : source.function();
                scope.Complete();
            }
            return outputItem;
        }
这可能吗?函数参数的类型是什么

在更复杂的方法中,我想向上述方法发送一个在我的范围内执行的操作列表,因为事务可能包含多个操作。这可能吗

public static TSource ReadUncommittedFunctions<TSource>(FunctionList functionList)
        {
            var transactionOptions = new TransactionOptions()
            {
                IsolationLevel = IsolationLevel.ReadUncommitted
            };
            TSource outputItem;
            using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
            {
                source.functionList.ElementAt(0)();
                source.functionList.ElementAt(1)();
                scope.Complete();
            }
            return outputItem;
        }

您可以尝试使用泛型Func,如下所示:

public static TSource ReadUncommittedAction<TSource>(Func<TSource> func)
{
  var transactionOptions = new TransactionOptions()
  {
      IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
  };
  TSource outputItem;
  using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
  {
      outputItem = func();
      scope.Complete();
  }
  return outputItem;
}
然后:

ReadUncommittedAction<SomeClass>(() => 
{
    // as many actions as needed
    return new SomeClass();
});

嗯。我可以想出一些方法来实现你想要的

首先,我认为您可以在范围内传递要在“源”上调用的函数的名称,并使用反射来调用正确的方法。很像这篇文章:

或者,你可以做与你的谓词相同的事情。。。扩展“ReadUncommittedFunctions”函数,将额外的Func作为参数。Func将范围和谓词作为输入,TSource作为输出。在Func中,对作用域应用desidered操作并返回结果。”ReadUncommittedFunctions'将在using块内调用Func


只是一个建议。

我认为这会导致功能丧失,因为OP不能再传递可选谓词。我认为可以通过将谓词变量添加回readUncommittedAction参数列表并使用Func来修复此问题。