Callback Requested Query Abort on Transaction - c#

I am using a recursive function that has a transaction in it, however the transaction causes a "callback requested query abort
abort due to ROLLBACK" error. Here is my code:
public Dictionary<int, string> GetFolders(string connectstring)
{
var connection = new SQLiteConnection(connectstring);
connection.Open();
Dictionary<int, string> folderdictionary = new Dictionary<int, string>();
using (var transaction = connection.BeginTransaction())
{
using (SQLiteCommand command = connection.CreateCommand())
{
command.CommandText = "select * from moz_bookmarks AS bookmarks WHERE type=2";
SQLiteDataReader commandread = command.ExecuteReader();
int current_id = 0;
List<string> currentfolders = new List<string>();
while (commandread.Read()) // <--------------- thrown here
{
var title = commandread.GetString(5);
current_id = commandread.GetInt32(0);
var parent = commandread.GetInt32(3);
List<string> folders = new List<string>();
folder = GetChild(connection, (string)commandread["title"], commandread.GetInt32(3), ref folders, true);
currentfolders.Add(folder);
folderdictionary.Add(current_id, folder);
folder = "";
}
}
transaction.Commit();
}
connection.Close();
return folderdictionary;
}
The recursion itself is in the GetChild function:
private static string GetChild(SQLiteConnection sqlite_connection2, string title, int id, ref List<string> folder, bool recursive, SQLiteTransaction transaction)
{
if (recursive)
folder.Add(title);
using (SQLiteCommand folder_get = sqlite_connection2.CreateCommand())
{
folder_get.Connection = sqlite_connection2;
folder_get.CommandText = "SELECT * FROM moz_bookmarks WHERE id = " + id;
SQLiteDataReader get_folders = folder_get.ExecuteReader();
while (get_folders.Read())
{
if (get_folders.GetInt32(1) == 1)
{
break;
}
else if (get_folders.GetInt32(1) == 2 && get_folders.GetInt32(0) != 1)
{
folder.Add(get_folders["title"].ToString());
if (get_folders.GetInt32(3) != 0 && get_folders.GetInt32(0) != 1)
{
GetChild(sqlite_connection2, (string)get_folders["title"], get_folders.GetInt32(3), ref folder, false);
}
break;
}
}
if (recursive)
folder.Reverse();
get_folders.Close();
}
return string.Join("\\", folder);
}
Without the SQLiteTransaction, the GetChild is a huge memory leak and eventually throws a OutOfMemoryException.

Related

C# - "Connection must be valid and open" with multiple Queries and Methods | Connection not closed?

For many hours now I have lost it over this same error no matter what I change.
I'm trying to make a command line application that will retrieve info from a database based off of two argument inputs, the modname and the optional author. The queries are all handled in the jobs.cs file. The entry-point file calls the method beginJob() which gets the target modname and author (if specified) to query. What's different from the hundred or so other posts I've read here is that the first query issued works completely fine, and I'm sure to close the reader and connection. (Won't close connection every time in production, but I did here for debugging purposes). The next time I call the connection it results in this error.
System.InvalidOperationException: Connection must be valid and open.
at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception)
at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex)
at MySql.Data.MySqlClient.MySqlCommand.CheckState()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
at vmcmod.Job.queryAuthor(String authorUID) in F:\Projects\VisualStudio\VMC-MOD\vmcmod\job.cs:line 235
at vmcmod.Job.StartJob() in F:\Projects\VisualStudio\VMC-MOD\vmcmod\job.cs:line 47
at vmcmod.Job.queryModAndAuthor(String modname, String author) in F:\Projects\VisualStudio\VMC-MOD\vmcmod\job.cs:line 205
at vmcmod.Job.beginJob() in F:\Projects\VisualStudio\VMC-MOD\vmcmod\job.cs:line 27
at vmcmod.VMCMOD.parseArgs() in F:\Projects\VisualStudio\VMC-MOD\vmcmod\vmcmod.cs:line 58
Some posts I've looked at but don't seem to help:
C# Mysql Connection must be valid and open
Connection must be valid and open error
C# Query: 'System.InvalidOperationException' | Additional information: Connection must be valid and open
C# Source Files (Please try and not cringe too hard, this is my first C# application):
jobs.cs [updated]
using MySql.Data.MySqlClient;
using System;
namespace vmcmod
{
class Job
{
public bool checkInput()
{
if (Global.currentJobTargetModname == "undefined")
{
Utils.consoleLog("The mod name is required.", 3);
return false;
}
else
{
return true;
}
}
public void beginJob()
{
string targetModname = Global.currentJobTargetModname.ToLower();
string targetModAuthor = Global.currentJobTargetAuthor.ToLower();
if (targetModAuthor != "undefined")
{
queryModAndAuthor(targetModname, targetModAuthor);
Utils.consoleLog("Job Call. (Author defined)", 4);
}
else
{
queryMod(targetModname);
Utils.consoleLog("Job Call. (Author undefined)", 4);
}
}
private void StartJob()
{
string author = null;
string targetModAuthor = Global.currentJobTargetAuthor.ToLower();
Utils.consoleLog("Mod exists.", 5);
if (targetModAuthor == "undefined")
{
author = "(None; First in row)";
}
else
{
queryAuthor(Global.queryResModAuthorID);
author = "'" + Global.queryResModAuthor + "' (UUID:" + Global.queryResModAuthorID + ") ";
}
var collaborators_obj = Newtonsoft.Json.Linq.JObject.Parse(Global.queryResModCollab);
var tags_obj = Newtonsoft.Json.Linq.JObject.Parse(Global.queryResModTags);
Console.BackgroundColor = ConsoleColor.Blue;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("MOD INSTALL SPECIFICATIONS:");
Console.BackgroundColor = ConsoleColor.Black;
Console.WriteLine(" Mod Name: '" + Global.queryResModName + "'");
Console.Write(" Mod Author: " + author);
if (Global.queryResModAuthorVerified == true && targetModAuthor != "undefined")
{
Utils.consoleTag("*VERIFIED*", ConsoleColor.Green);
}
if (Global.queryResModAuthorVerified == false && targetModAuthor != "undefined")
{
Utils.consoleTag("*UNVERIFIED*", ConsoleColor.Red);
}
Console.Write("\n");
Console.WriteLine(" Mod Version: " + Global.queryResModVersion);
Console.WriteLine(" Installations: " + Global.queryResModInstalls);
Console.WriteLine(" Description:\n " + Global.queryResDescription);
Console.WriteLine(" Mod UUID: " + Global.queryResModUid);
if (Global.advInfo == true)
{
Console.WriteLine(" Rep. Entry #" + Global.queryResModID);
Console.WriteLine(" Mod Created On: " + Utils.UnixTimeStampToDateTime(Convert.ToDouble(Global.queryResDateCreated)));
Console.WriteLine(" Mod Last Modified On: " + Utils.UnixTimeStampToDateTime(Convert.ToDouble(Global.queryResDateLastModf)));
Console.WriteLine(" Tags: \n " + Convert.ToString(tags_obj["tags"]));
Console.WriteLine(" Collaborators: \n " + Convert.ToString(collaborators_obj["collaborators"]));
}
Utils.consoleSeparator();
bool user_response = Utils.consoleAskYN("Are you sure you want to install this mod?");
if (user_response == true)
{
queryGetModJSON(Global.queryResModUid);
Utils.consoleLog("JSON Data: "+Global.queryResModJSON,5);
//FileIO fio = new FileIO();
//fio.jsonToFiles(fio.jsonToArray(Global.queryResModJSON));
}
else
{
Utils.consoleSetKeyExit();
}
}
private void queryGetModJSON(string uuid)
{
var dbCon = new DBConnection();
if (dbCon.IsConnect() == false)
{
Utils.consoleLog("Unable to query repository or no results.", 3);
Utils.consoleSetKeyExit();
}
else
{
string q = "SELECT data_json FROM vmcmod_repository_data WHERE uid='" + uuid + "' LIMIT 1;";
MySqlCommand cmd = new MySqlCommand(q, dbCon.Connection);
var reader = cmd.ExecuteReader();
if (!reader.HasRows)
{
Utils.consoleLog("Mod data not found.", 3);
reader.Close();
dbCon.Close();
}
else
{
while (reader.Read())
{
Global.queryResModJSON = reader.GetString(0);
}
reader.Close();
dbCon.Close();
}
}
}
private void queryMod(string modname)
{
var dbCon = new DBConnection();
if (dbCon.IsConnect() == false)
{
Utils.consoleLog("Unable to query repository or no results.", 3);
Utils.consoleSetKeyExit();
}
else
{
string q = "SELECT id,uid,author_id,mod_name,status,dependencies_json,description,mod_version,date_created,date_last_modified,collaborators,tags_json,installs FROM vmcmod_repository_info WHERE mod_name LIKE'" + modname + "' LIMIT 1;";
MySqlCommand cmd = new MySqlCommand(q, dbCon.Connection);
var reader = cmd.ExecuteReader();
if (!reader.HasRows)
{
Utils.consoleLog("Mod not found.", 3);
reader.Close();
dbCon.Close();
}
else
{
while (reader.Read())
{
Global.queryResModInstalls = reader.GetInt32(12);
Global.queryResModTags = reader.GetString(11);
Global.queryResModCollab = reader.GetString(10);
Global.queryResDateLastModf = reader.GetInt32(9);
Global.queryResDateCreated = reader.GetInt32(8);
Global.queryResModVersion = reader.GetFloat(7);
Global.queryResDescription = reader.GetString(6);
Global.queryResModDependencies = reader.GetString(5);
Global.queryResModStatus = reader.GetInt16(4);
Global.queryResModName = reader.GetString(3);
Global.queryResModAuthorID = reader.GetString(2);
Global.queryResModUid = reader.GetString(1);
Global.queryResModID = Convert.ToInt32(reader.GetInt32(0));
}
reader.Close();
dbCon.Close();
StartJob();
}
}
}
private void queryModAndAuthor(string modname, string author)
{
var dbCon = new DBConnection();
if (dbCon.IsConnect() == false)
{
Utils.consoleLog("Unable to query repository or no results.", 3);
Utils.consoleSetKeyExit();
}
else
{
string q = "SELECT id,uid,author_id,mod_name,status,dependencies_json,description,mod_version,date_created,date_last_modified,collaborators,tags_json,installs FROM vmcmod_repository_info WHERE mod_name LIKE'" + modname + "' LIMIT 1;";
MySqlCommand cmd = new MySqlCommand(q, dbCon.Connection);
var reader = cmd.ExecuteReader();
if (!reader.HasRows)
{
Utils.consoleLog("Mod not found.", 3);
reader.Close();
dbCon.Close();
}
else
{
while (reader.Read())
{
Global.queryResModInstalls = reader.GetInt32(12);
Global.queryResModTags = reader.GetString(11);
Global.queryResModCollab = reader.GetString(10);
Global.queryResDateLastModf = reader.GetInt32(9);
Global.queryResDateCreated = reader.GetInt32(8);
Global.queryResModVersion = reader.GetFloat(7);
Global.queryResDescription = reader.GetString(6);
Global.queryResModDependencies = reader.GetString(5);
Global.queryResModStatus = reader.GetInt16(4);
Global.queryResModName = reader.GetString(3);
Global.queryResModAuthorID = reader.GetString(2);
Global.queryResModUid = reader.GetString(1);
Global.queryResModID = Convert.ToInt32(reader.GetInt32(0));
}
reader.Close();
dbCon.Close();
StartJob();
}
}
}
private bool queryCheckAuthorExists(string author)
{
var dbCon = new DBConnection();
string q = "SELECT * FROM vmcmod_users WHERE username='"+author+ "' AND is_author=true LIMIT 1;";
MySqlCommand cmd = new MySqlCommand(q, dbCon.Connection);
var reader = cmd.ExecuteReader();
if (reader.HasRows == false)
{
Utils.consoleLog("Author not found.", 3);
reader.Close();
dbCon.Close();
return false;
}
else
{
Utils.consoleLog("Author found.", 4);
reader.Close();
dbCon.Close();
return true;
}
}
private void queryAuthor(string authorUID)
{
var dbCon = new DBConnection();
string q = "SELECT username,is_verified_user FROM vmcmod_users WHERE uid='" + authorUID + "' AND is_author=true LIMIT 1;";
MySqlCommand cmd = new MySqlCommand(q, dbCon.Connection);
var reader = cmd.ExecuteReader();
if (reader.HasRows == false)
{
Utils.consoleLog("Author not found.", 3);
reader.Close();
dbCon.Close();
}
else
{
while (reader.Read())
{
Global.queryResModAuthor = reader.GetString(0);
Global.queryResModAuthorVerified = reader.GetBoolean(1);
}
Utils.consoleLog("Author found.", 4);
reader.Close();
dbCon.Close();
}
}
}
}
dbinterface.cs (this wasn't written by me, rather taken and edited from a post on stackoverflow, here) [updated]
using MySql.Data.MySqlClient;
using System;
namespace vmcmod
{
public class DBConnection
{
public DBConnection()
{
}
public string Password { get; set; }
private MySqlConnection connection = null;
public MySqlConnection Connection
{
get { return connection; }
}
public bool IsConnect()
{
bool result = true;
if (Connection == null)
{
string connString = "Server=...; Port=...; Database=...; Uid=...; Pwd=...;";
connection = new MySqlConnection(connString);
try
{
connection.Open();
Utils.consoleLog("Connected to repository.", 4);
result = true;
}
catch (Exception e)
{
Utils.consoleLog("Error occured while connecting to repository.", 3);
Utils.consoleLog("MySQL Exception: "+e,5);
result = false;
}
}
return result;
}
public void Close()
{
connection.Close();
connection = null;
}
}
}
global.cs (global variable storage)
using System;
namespace vmcmod
{
class Global
{
internal const float version = 0.1F;
internal static string currentJobWorld = "New World";
internal static string currentJobTargetModname = "undefined";
internal static string currentJobTargetAuthor = "undefined";
internal static string currentJobProfile = "default";
internal static int currentJobAccountPIN;
internal static bool verbose = false;
internal static bool debug = false;
internal static bool advInfo = false;
internal static bool queryResModAuthorVerified = false;
internal static string queryResModUid;
internal static string queryResModAuthorID;
internal static string queryResModAuthor;
internal static string queryResModName;
internal static string queryResModDependencies = "{\"dependencies\":[]}";
internal static int queryResModStatus;
internal static float queryResModVersion;
internal static string queryResDescription = "None provided.";
internal static int queryResDateCreated;
internal static int queryResDateLastModf;
internal static int queryResModID;
internal static string queryResModCollab = "{\"collaborators\":[]}";
internal static string queryResModTags = "{\"tags\":[]}";
internal static int queryResModInstalls;
internal static string queryResModJSON = "{}";
}
}
The quick and dirty solution would be to change:
public void Close()
{
connection.Close();
}
to:
public void Close()
{
connection.Close();
connection = null;
}
Also, remove this code:
private static DBConnection _instance = null;
public static DBConnection Instance()
{
if (_instance == null)
_instance = new DBConnection();
return _instance;
}
and rather than use DBConnection.Instance, just use new DBConnection();
And change:
public MySqlConnection Connection
{
get { return connection; }
}
to:
public MySqlConnection Connection
{
get {
IsConnect();
return connection; }
}
and change:
public bool IsConnect()
{
bool result = true;
if (Connection == null)
to:
public bool IsConnect()
{
bool result = true;
if (connection == null)
I see you are using singletne pattern for DBConnection this is not a good idea.
private static DBConnection _instance = null;
public static DBConnection Instance()
{
if (_instance == null)
_instance = new DBConnection();
return _instance;
}
You might want to check this answer out for more information: https://stackoverflow.com/a/814606/8143718
As per #mjwills' response, the DB interface script I'd swiped was quite funky and only allowed one instance at a time.
Working DB Interface
using MySql.Data.MySqlClient;
using System;
namespace vmcmod
{
public class DBConnection
{
public DBConnection()
{
}
public string Password { get; set; }
private MySqlConnection connection = null;
public MySqlConnection Connection
{
get
{
IsConnect();
return connection;
}
}
public bool IsConnect()
{
bool result = true;
if (connection == null)
{
string connString = "Server=...; Port=...; Database=...; Uid=...; Pwd=...;";
connection = new MySqlConnection(connString);
try
{
connection.Open();
Utils.consoleLog("Connected to repository.", 4);
result = true;
}
catch (Exception e)
{
Utils.consoleLog("Error occured while connecting to repository.", 3);
Utils.consoleLog("MySQL Exception: "+e,5);
result = false;
}
}
return result;
}
public void Close()
{
connection.Close();
connection = null;
}
}
}

Returning JSON from dynamic SQL query

In my data access layer when I want to serialize something into JSON and give it to the client I've been doing something like
using (var con = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand("spGetLengthsOfStay", con))
{
con.Open();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
var los = new LOS();
los.VisitId = (int)rdr["VisitId"];
los.PatientId = (int)rdr["PatientId"];
los.Gender = (string)rdr["Gender"];
los.Age = (int)rdr["Age"];
los.Discharge = (string)rdr["Discharge"];
los.LengthOfStay = (int)rdr["LengthOfStay"];
losList.Add(los);
}
}
}
There are some instances where I need to query the database with a dynamically generated SQL query, so I don't always know the properties to create a single instance of the object, add it to a list, and return the list. What's the preferred method for getting the results from a SQL query back to the client all at one, without using a concrete type using .NET MVC?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Dynamic;
using Newtonsoft.Json;
// microsoft sqlserver
using System.Data.SqlClient;
// oracle
using Oracle.ManagedDataAccess.Client;
namespace InqdWeb
{
public class Dbio
{
//
public static class Consts
{
public const string msgname = "retmsg";
public const string valname = "retval";
public const string jsond = "{ }";
public const string jsonr = "{ \"" + msgname + "\": \"OK\" }";
}
//
//
// »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
// core functions
// »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
//
//
// with a "sql statement"
// and a connection id,
// prepare the actual sql to get data
// return the result as json
public static string sqljson
(string pi_sql
, string pi_conn
)
{
// empty data
var vd = Consts.jsond;
// success message
var vr = Consts.jsonr;
string msgout = "00";
var ld = new List<dynamic>();
ld = sqlmaster(pi_sql, pi_conn, out msgout);
//
if (msgout.Substring(0, 2) == "00") // not empty and no errors
{
vd = JsonConvert.SerializeObject(ld);
vr = Consts.jsonr.Replace("OK", "00");
}
if (msgout.Substring(0, 2) == "10") // empty and no errors
{
vr = Consts.jsonr.Replace("OK", "10");
}
if (msgout.Substring(1, 1) == "1") // error
{
vd = JsonConvert.SerializeObject(ld);
vr = Consts.jsonr.Replace("OK", msgout);
}
// return json with 2 collections: d with data, r with status and message
var vt = jsonmerge(vd, vr);
return vt;
}
//
//
//
// with a sql
// and a conn id
// return data as dynamic list
public static List<dynamic> sqlmaster
(string pi_sql
, string pi_conn
, out string po_msg
)
{
string sql = " ";
sql = pi_sql;
// result
po_msg = msgout;
// po_msg pos1 empty: 1 has rows: 0
// pos2 error: >0 no error: 0
// pos3... error message
return lista;
}
//
//
// with a sql statement
// and a connection string
// return the result on a dynamic list
// plus a string with
// pos1 error 0-ok 1-error
// pos2 list empty 0-ok 1-list is empty
// pos3... message return code from non-select or error message
public static List<dynamic> sqldo
(string pi_sql
, string pi_connstring
, out string msgout
)
{
// variables
string sql = pi_sql;
var lista = new List<dynamic>();
int retcode;
msgout = "0";
//
string ConnString = pi_connstring;
//
//
//
// Microsoft SqlServer
if (SqlFlavor == "Ms")
{
using (SqlConnection con = new SqlConnection(ConnString))
{
try
{
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
if (sqltype == "R")
{
SqlDataReader reada = cmd.ExecuteReader();
string datatype = "-";
string colname = "-";
while (reada.Read())
{
var obj = new ExpandoObject();
var d = obj as IDictionary<String, object>;
//
for (int index = 0; index < reada.FieldCount; index++)
{
datatype = reada.GetDataTypeName(index);
colname = reada.GetName(index);
bool isnul = reada.IsDBNull(index);
if (!isnul)
{
// add datatypes as needed
switch (datatype)
{
case "int":
d[colname] = reada.GetValue(index);
break;
case "varchar":
d[colname] = reada.GetString(index);
break;
case "nvarchar":
d[colname] = reada.GetString(index);
break;
case "date":
d[colname] = reada.GetDateTime(index);
break;
default:
d[colname] = reada.GetString(index);
break;
}
}
else
{
d[colname] = "";
}
}
lista.Add(obj);
}
reada.Close();
}
}
catch (Exception ex)
{
msgout = "11" + ex.Message.ToString();
}
}
}
//
// Oracle
if (SqlFlavor == "Oa")
{
// Or uses a "
sql = sql.Replace("[", "\"");
sql = sql.Replace("]", "\"");
using (OracleConnection con = new OracleConnection(ConnString))
{
try
{
con.Open();
//
OracleCommand cmd = new OracleCommand(sql, con);
OracleDataReader reada = cmd.ExecuteReader();
string datatype = "-";
string colname = "-";
while (reada.Read())
{
var obj = new ExpandoObject();
var d = obj as IDictionary<String, object>;
// browse every column
for (int index = 0; index < reada.FieldCount; index++)
{
datatype = reada.GetDataTypeName(index);
colname = reada.GetName(index);
bool isnul = reada.IsDBNull(index);
if (!isnul)
{
// add datatypes as needed
switch (datatype)
{
case "Decimal":
d[colname] = reada.GetValue(index);
break;
case "Varchar":
d[colname] = reada.GetString(index);
break;
default:
d[colname] = reada.GetString(index);
break;
}
}
else
{
d[colname] = "";
}
}
lista.Add(obj);
}
reada.Close();
//
}
catch (Exception ex)
{
msgout = "11" + ex.Message.ToString();
}
}
}
//
//
//
return lista;
}
//
//
}
Use it in your controller
string vret = "{'r':{'retval': 'OK' }}";
string sqltxt;
string connt;
connt = ConfigurationManager.ConnectionStrings["<your connection>"].ConnectionString;
sqltxt = "<your select>";
vret = Dbio.sqljson(sqltxt, connt, "MsX"); // MsX for MsSqlServer
return Content(vret, "application/json");

The out parameter 'recordsReturned' must be assigned to before control leaves the current method ObjectCache

I'm stuck on trying to work out how to solve the error above, how can i assign the value to recordsReturned which is an output parameter from the database and add it to ObjectCache.
Before the data is cached I can get the value, but I cannot add it to the cache, i have tried out and ref, but with no luck.
Hopefully someone with more experience than me can help with my problem.
I've added my code below:
public class RetrieveTravelGuideForSearchResults : IRetrieveTravelGuideForSearchResults
{
private readonly string _dbConn;
public RetrieveTravelGuideForSearchResults()
{
_dbConn = ConfigurationManager.ConnectionStrings["ADO_DBConn"].ConnectionString;
}
public IEnumerable<DisplayTravelGuideForSearchResults> DisplayTravelGuideSearchResults(string id,out int recordsReturned)
{
string cacheData = "DisplayTravelGuideSearchResults" + RegexHelpers.RegexRemoveAllInvalidCharactersAndSpace(id.ToLower());
ObjectCache travelGuideCache = MemoryCache.Default;
var objectInCache = travelGuideCache.Get(cacheData) as IEnumerable<DisplayTravelGuideForSearchResults>;
//recordsReturned = 0;
if (objectInCache != null)
{
recordsReturned = 0; //How can I get value from output parameter and add it here
return objectInCache;
}
const string spName = "dbo.spFTSTravelGuide";
//recordsReturned = 0;
using (var cn = new SqlConnection(_dbConn))
{
using (var cmd = new SqlCommand(spName, cn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#SearchPhrase", SqlDbType.VarChar, 100));
cmd.Parameters["#SearchPhrase"].Value = id;
cmd.Parameters.Add(new SqlParameter("#RecordsReturn", SqlDbType.Int));
cmd.Parameters["#RecordsReturn"].Direction = ParameterDirection.Output;
var data = new List<DisplayTravelGuideForSearchResults>();
try
{
cn.Open();
using (var rdr = cmd.ExecuteReader(CommandBehavior.Default))
{
if (rdr.HasRows)
{
while (rdr.Read())
{
data.Add(new DisplayTravelGuideForSearchResults
{
Country = (string)rdr["TravelGuideCountry"],
Description = RegexHelpers.RegexRemoveHtmlTags((string)rdr["TravelGuideDescription"])
});
}
}
}
var policy = new CacheItemPolicy { AbsoluteExpiration = DateTime.Now.AddMinutes(15) };
travelGuideCache.Add(cacheData, data, policy);
recordsReturned = cmd.Parameters["#RecordsReturn"].Value as int? ?? 0;
return data;
}
catch (SqlException ex)
{
throw new ApplicationException(ex.InnerException.ToString());
}
catch (Exception ex)
{
throw new ApplicationException(ex.InnerException.ToString());
}
}
}
}
}
have got the answer to my problem, should have done
recordsReturned = cmd.Parameters["#RecordsReturn"].Value as int? ?? 0;
travelGuideCache.Add("recordsReturned", recordsReturned, policy);
and then
if (objectInCache != null)
{
recordsReturned = travelGuideCache.Get("recordsReturned") as int? ?? 0;
return objectInCache;
}
This now get the output parameter value and allows me to cache it.

How to prevent resources from being consumed by long-running queries?

I hava access DB, one of my function(C#.net) need to Exec a SQL more than 4000 times with transaction.
It seems that after execution the DB file stay opened exclusively. because there is a *.ldb file, and that file stay there for a long time.
Is that caused by dispose resources incorrectly???
private int AmendUniqueData(Trans trn)
{
int reslt = 0;
foreach (DataRow dr in _dt.Rows)
{
OleDbParameter[] _params = {
new OleDbParameter("#templateId",dr["Id"].ToString()),
new OleDbParameter("#templateNumber",dr["templateNumber"].ToString())
};
string sqlUpdateUnique = "UPDATE " + dr["proformaNo"].ToString().Substring(0,2) + "_unique SET templateId = #templateId WHERE templateNumber=#templateNumber";
reslt = OleDBHelper.ExecSqlWithTran(sqlUpdateUnique, trn, _params);
if (reslt < 0)
{
throw new Exception(dr["id"].ToString());
}
}
return reslt;
}
the transaction:
using (Trans trn = new Trans())
{
try
{
int reslt=AmendUniqueData(trn);
trn.Commit();
return reslt;
}
catch
{
trn.RollBack();
throw;
}
finally
{
trn.Colse();
}
}
forget closing the database connection.

c# how to set the code run at final

I need to set the line of code to run after everything has finish run. Anyone know how to do that?
private void ScanBT_Click(object sender, EventArgs e)
{
var folder = #"C:\Users\Shen\Desktop\LenzOCR\LenzOCR\WindowsFormsApplication1\ImageFile";
DirectoryInfo directoryInfo;
FileInfo[] files;
directoryInfo = new DirectoryInfo(folder);
files = directoryInfo.GetFiles("*.jpg", SearchOption.AllDirectories);
var processImagesDelegate = new ProcessImagesDelegate(ProcessImages2);
processImagesDelegate.BeginInvoke(files, null, null);
**//HERE IS THE LINE OF CODE THAT NEED TO BE RUN AFTER EVERYTHING FINISH RUN
System.IO.File.Delete(#"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg");**
}
private void ProcessImages2(FileInfo[] files)
{
var comparableImages = new List<ComparableImage>();
var index = 0x0;
foreach (var file in files)
{
if (exit)
{
return;
}
var comparableImage = new ComparableImage(file);
comparableImages.Add(comparableImage);
index++;
}
index = 0;
similarityImagesSorted = new List<SimilarityImages>();
//MessageBox.Show("here"+singleFileInfo.FullName);
var fileImage = new ComparableImage(singleFileInfo);
for (var i = 0; i < comparableImages.Count; i++)
{
if (exit)
return;
var destination = comparableImages[i];
var similarity = fileImage.CalculateSimilarity(destination);
var sim = new SimilarityImages(fileImage, destination, similarity);
similarityImagesSorted.Add(sim);
index++;
}
similarityImagesSorted.Sort();
similarityImagesSorted.Reverse();
similarityImages = new BindingList<SimilarityImages>(similarityImagesSorted);
var buttons =
new List<Button>
{
ScanBT
};
if (similarityImages[0].Similarity > 70)
{
con = new System.Data.SqlClient.SqlConnection();
con.ConnectionString = "Data Source=SHEN-PC\\SQLEXPRESS;Initial Catalog=CharacterImage;Integrated Security=True";
con.Open();
String getFile = "SELECT ImageName, Character FROM CharacterImage WHERE ImageName='" + similarityImages[0].Destination.ToString() + "'";
SqlCommand cmd2 = new SqlCommand(getFile, con);
SqlDataReader rd2 = cmd2.ExecuteReader();
while (rd2.Read())
{
for (int i = 0; i < 1; i++)
{
string getText = rd2["Character"].ToString();
Action showText = () => ocrTB.AppendText(getText);
ocrTB.Invoke(showText);
}
}
con.Close();
}
else
{
MessageBox.Show("No character found!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
How about move the line of code to delete the file to the end of the process images method?
Run the code inside ProcessImages2 method in a BackgroundWorker.DoWork(...)
Substitute ProcessImagesDelegate.BeginInvoke(files, null, null) with worker.RunWorkerAsync(...)
Trap the event RunWorkerCompleted and execute there the File.Delete(...).
In this way your main thread is free to be refreshed and used by end-user.
If you edit the method like below the call will block until ProcessImages2 is completed.
var processImagesDelegate = new ProcessImagesDelegate(ProcessImages2);
IAsyncResult result = processImagesDelegate.BeginInvoke(files, null, null);
result.AsyncWaitHandle.WaitOne();
**//HERE IS THE LINE OF CODE THAT NEED TO BE RUN AFTER EVERYTHING FINISH RUN
System.IO.File.Delete(#"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg");

Categories

Resources