c# - Parallel.Foreach SQL querying sometimes results in Connection -
i need speed performing 12 queries in application. switched regular foreach parallel.foreach. error saying "executereader requires open , available connection connection's current state connecting." understanding since many of 12 queries using same initialcatalog, there not new connection of 12 , may problem? how can fix this? "sql" list of type "sql"- class string name, string connectiona , list of queries. here code:
/// <summary> /// connects sql, performs queries , stores results in list of datatables /// </summary> /// <returns>list of data tables each query in config file</returns> public list<datatable> getalldata() { stopwatch sw = new stopwatch(); sw.start(); list<datatable> data = new list<datatable>(); list<sql> sql=new list<sql>(); sql 1 = new sql(); one.connection = "data source=xxx-sql1;initial catalog=xxxdb;integrated security=true"; one.name = "col1"; one.queries.add("select name [reports]"); one.queries.add("select other [reports2]"); sql.add(one); sql 2 = new sql(); two.connection = "data source=xxx-sql1;initial catalog=xxxdb;integrated security=true"; two.name = "col2"; two.queries.add("select alternatename [reports1]"); sql.add(two); sql 3 = new sql(); three.connection = "data source=yyy-sql2;initial catalog=yyydb;integrated security=true"; three.name = "col3"; three.queries.add("select frequency times"); sql.add(three); try { // paralleloptions options = new paralleloptions(); //options.maxdegreeofparallelism = 3; // parallel.foreach(sql, options, s => parallel.foreach(sql, s => //foreach (sql s in sql) { foreach (string q in s.queries) { using (connection = new sqlconnection(s.connection)) { connection.open(); datatable dt = new datatable(); dt.tablename = s.name; command = new sqlcommand(q, connection); sqldataadapter adapter = new sqldataadapter(); adapter.selectcommand = command; adapter.fill(dt); //adapter.dispose(); lock (data) { data.add(dt); } } } } ); } catch (exception ex) { messagebox.show(ex.tostring(), "getalldata error"); } sw.stop(); messagebox.show(sw.elapsed.tostring()); return data; } here's sql class made you'd need:
/// <summary> /// class defines sql connection , respective queries /// </summary> public class sql { /// <summary> /// name of connection/query /// </summary> public string name { get; set; } /// <summary> /// sql connection string /// </summary> public string connection { get; set; } /// <summary> /// list of sql queries connection /// </summary> public list<string> queries = new list<string>(); }
i refactor out business logic (connecting database).
public class sqloperation { public sqloperation() { queries = new list<string>(); } public string tablename { get; set; } public string connectionstring { get; set; } public list<string> queries { get; set; } } public static list<datatable> getalldata(ienumerable<sqloperation> sql) { var taskarray = sql.selectmany(s => s.queries .select(query => task.run(() => //task.factory.startnew .net 4.0 executequery(s.connectionstring, s.tablename, query)))) .toarray(); try { task.waitall(taskarray); } catch(aggregateexception e) { messagebox.show(e.tostring(), "getalldata error"); } return taskarray.where(t => !t.isfaulted).select(t => t.result).tolist(); } public static datatable executequery(string connectionstring, string tablename, string query) { datatable datatable = null; using (var connection = new sqlconnection(connectionstring)) { datatable = new datatable(); datatable.tablename = tablename; using(var command = new sqlcommand(query, connection)) { connection.open(); using(var adapter = new sqldataadapter()) { adapter.selectcommand = command; adapter.fill(datatable); } } } return datatable; }
Comments
Post a Comment