Change DataContext IQueryable

I am working on a project that uses a static global DataContext (which is not recommended, but very difficult to change at this stage). Currently I need to increase the performance of some parts by parallelizing some independent functions. Since the DataContext is not thread safe, I cannot use it on newly created threads. So I created a new DataContext inside each thread and placed it at the end of the thread.

Everything is fine with the new datacontext, but I have a problem that one of the inputs to this function is IQueryable, which is bound to the global DataContext. Running the method will result in the exception "There is an already open DataReader associated with this Command and must be closed first."

The question is, how can I start an IQueryable with a new data context instead of a changed one.

Please find below example code for streams:

var myQueryable = Global.DataContext.Customers.Where(a => a.Age <12);

ParallelLoopResult threads = Parallel.ForEach(groups, group =>
        {
            DataContext ctx = new DataContext(Const.ConnectionString);
            myFunction(myQueryable);
            ctx.Dispose();
        });

      

Being able to overwrite myQueryable inside a thread is unfortunately quite tricky as there is a lot of logic to create it. Converting it to a list and then passing it in is also not an option, as the query returns thousands of records and will negatively impact performance.

Any help is appreciated

+3


source to share


1 answer


I haven't tested this, but I think it might work to get your query using the correct Expression

one but the wrong one, Provider

and combine it with the one that has the right Provider

one but the wrong one Expression

. To do this, use CreateQuery()

:



var contextQueryable = ctx.Customers;

var fixedQueryable = contextQueryable.Provider.CreateQuery<Customer>(myQueryable.Expression);

      

+3


source







All Articles