I am working in creating a generic method that allows me to include inside a transaction scope each of the operations of the database. Currently I have multiple LINQ to SQL operations in my code such as:
var myVar = MyContext.First(c => c.Id == myId);
What I have right now are generic methods for each of the possible operations such as Count, First, FirstOrDefault, ToList, etc:
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;
}
However, I would like a more generic approach in which I can somehow pass as an argument the method I want to apply to the query as follows:
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;
}
Is this possible? What would be the type of the function argument?
On a more complicated approach, I would like to send into the above mentioned method a list of operations to be performed inside my scope (because the transaction may consist of multiple operations). Is this possible?
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;
}