I wrote C# code which returns a DataTable. All parameters i.e. Connection, sQuery have proper values.
Still I am getting an error:
In the name the owner of a procedure must be specified, this improves performance
I googled it but found nothing.
This is my code:
public static DataTable getATM(ref SqlConnection Connection)
{
DataTable dtReturn;
string sQuery = "";
try
{
sQuery = "Select ATM From ATM Where Bank=1";
using (SqlStoredProcedure sspObj = new SqlStoredProcedure(sQuery, Connection, CommandType.Text))
{
dtReturn = sspObj.ExecuteDataTable();
sspObj.Dispose();
}
}
catch (Exception xObj)
{
dtReturn = new DataTable();
}
return dtReturn;
}
SqlStoredProcedure.cs:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Xml;
using System.Diagnostics;
namespace ReflectionIT.Common.Data.SqlClient {
public class SqlStoredProcedure : IDisposable {
public static readonly TraceSource TraceSource = new TraceSource("SqlStoredProcedure");
private static int _eventId = 0;
private const string _returnValue = "ReturnValue";
private SqlCommand _command;
private bool _connectionOpened = false;
public SqlStoredProcedure(string name, SqlConnection connection, CommandType comtype)
: this(name, connection, null, comtype) {
}
public SqlStoredProcedure(string name, SqlConnection connection, SqlTransaction transaction, CommandType comtype) {
if (name.IndexOf('.') == -1) {
throw new ArithmeticException("In the name the owner of a procedure must be specified, this improves performance");
}
_command = new SqlCommand(name, connection, transaction);
_command.CommandTimeout = 0;
_command.CommandType = comtype;
AddReturnValue();
}
public void Dispose() {
if (_command != null) {
_command.Dispose();
_command = null;
}
}
virtual public string Name {
get { return _command.CommandText; }
set { _command.CommandText = value; }
}
virtual public int Timeout {
get { return _command.CommandTimeout; }
set { _command.CommandTimeout = value; }
}
virtual public SqlCommand Command {
get { return _command; }
}
virtual public SqlConnection Connection {
get { return _command.Connection; }
set { _command.Connection = value; }
}
virtual public SqlTransaction Transaction {
get { return _command.Transaction; }
set { _command.Transaction = value; }
}
virtual public SqlParameterCollection Parameters {
get { return _command.Parameters; }
}
virtual public int ReturnValue {
get { return (int)_command.Parameters[_returnValue].Value; }
}
virtual public SqlParameter AddParameter(string parameterName,
SqlDbType dbType,
int size,
ParameterDirection direction) {
SqlParameter p;
if (size > 0) {
p = new SqlParameter(parameterName, dbType, size);
} else {
// size is automacally detected using dbType
p = new SqlParameter(parameterName, dbType);
}
p.Direction = direction;
Parameters.Add(p);
return p;
}
virtual public SqlParameter AddParameterWithValue(string parameterName,
SqlDbType dbType,
int size,
ParameterDirection direction,
object value) {
SqlParameter p = this.AddParameter(parameterName, dbType, size, direction);
if (value == null) {
value = DBNull.Value;
}
p.Value = value;
return p;
}
virtual public SqlParameter AddParameterWithStringValue(string parameterName,
SqlDbType dbType,
int size,
ParameterDirection direction,
string value,
bool emptyIsDBNull) {
SqlParameter p = this.AddParameter(parameterName, dbType, size, direction);
if (value == null) {
p.Value = DBNull.Value;
} else {
value = value.TrimEnd(' ');
if (emptyIsDBNull && value.Length == 0) {
p.Value = DBNull.Value;
} else {
p.Value = value;
}
}
return p;
}
virtual protected SqlParameter AddReturnValue() {
SqlParameter p = Parameters.Add(
new SqlParameter(_returnValue,
SqlDbType.Int,
/* int size */ 4,
ParameterDirection.ReturnValue,
/* bool isNullable */ false,
/* byte precision */ 0,
/* byte scale */ 0,
/* string srcColumn */ string.Empty,
DataRowVersion.Default,
/* value */ null));
return p;
}
virtual public int ExecuteNonQuery() {
int rowsAffected = -1;
try {
Prepare("ExecuteNonQuery");
rowsAffected = _command.ExecuteNonQuery();
TraceResult("RowsAffected = " + rowsAffected.ToString());
} catch (SqlException e) {
throw TranslateException(e);
} finally {
CloseOpenedConnection();
}
return rowsAffected;
}
virtual public SqlDataReader ExecuteReader() {
SqlDataReader reader;
try {
Prepare("ExecuteReader");
reader = _command.ExecuteReader();
TraceResult(null);
} catch (SqlException e) {
throw TranslateException(e);
} finally {
CloseOpenedConnection();
}
return reader;
}
virtual public SqlDataReader ExecuteReader(CommandBehavior behavior) {
SqlDataReader reader;
try {
Prepare("ExecuteReader");
reader = _command.ExecuteReader(behavior);
TraceResult(null);
} catch (SqlException e) {
throw TranslateException(e);
} finally {
CloseOpenedConnection();
}
return reader;
}
virtual public object ExecuteScalar() {
object val = null;
try {
Prepare("ExecuteScalar");
val = _command.ExecuteScalar();
TraceResult("Scalar Value = " + Convert.ToString(val));
} catch (SqlException e) {
throw TranslateException(e);
} finally {
CloseOpenedConnection();
}
return val;
}
virtual public XmlReader ExecuteXmlReader() {
XmlReader reader;
try {
Prepare("ExecuteXmlReader");
reader = _command.ExecuteXmlReader();
TraceResult(null);
} catch (SqlException e) {
throw TranslateException(e);
} finally {
CloseOpenedConnection();
}
return reader;
}
virtual public DataSet ExecuteDataSet() {
DataSet dataset = new DataSet();
this.ExecuteDataSet(dataset);
return dataset;
}
virtual public DataSet ExecuteDataSet(DataSet dataSet) {
try {
Prepare("ExecuteDataSet");
SqlDataAdapter a = new SqlDataAdapter(this.Command);
a.Fill(dataSet);
TraceResult("# Tables in DataSet = " + dataSet.Tables.Count);
} catch (SqlException e) {
throw TranslateException(e);
} finally {
CloseOpenedConnection();
}
return dataSet;
}
virtual public DataTable ExecuteDataTable() {
DataTable dt = null;
try {
Prepare("ExecuteDataTable");
SqlDataAdapter a = new SqlDataAdapter(this.Command);
dt = new DataTable();
a.Fill(dt);
TraceResult("# Rows in DataTable = " + dt.Rows.Count);
} catch (SqlException e) {
throw TranslateException(e);
} finally {
CloseOpenedConnection();
}
return dt;
}
protected Exception TranslateException(SqlException ex) {
Exception dalException = null;
SqlStoredProcedure.TraceSource.TraceEvent(TraceEventType.Error, _eventId, "{0} throwed exception: {1}", this.Name, ex.ToString());
foreach (SqlError error in ex.Errors) {
if (error.Number >= 50000) {
dalException = new DalException(error.Message, ex);
}
}
if (dalException == null) {
switch (ex.Number) {
case 17:
case 4060:
case 18456:
dalException = new DalLoginException(ex.Message, ex);
break;
case 547:
dalException = new DalForeignKeyException(ex.Message, ex);
break;
case 1205:
dalException = new DalDeadLockException(ex.Message, ex);
break;
case 2627:
case 2601:
dalException = new DalUniqueConstraintException(ex.Message, ex);
break;
default:
dalException = new DalException(ex.Message, ex);
break;
}
}
return dalException;
}
protected void Prepare(string executeType) {
_eventId++;
if (_eventId > ushort.MaxValue) {
_eventId = 0;
}
SqlStoredProcedure.TraceSource.TraceEvent(TraceEventType.Information, _eventId, "{0}: {1}", executeType, this.Name);
TraceParameters(true);
if (_command.Connection.State != ConnectionState.Open) {
_command.Connection.Open();
_connectionOpened = true;
}
}
private void TraceParameters(bool input) {
if (SqlStoredProcedure.TraceSource.Switch.ShouldTrace(TraceEventType.Verbose) && this.Parameters.Count > 0) {
foreach (SqlParameter p in this.Parameters) {
bool isInput = p.Direction != ParameterDirection.ReturnValue && p.Direction != ParameterDirection.Output;
bool isOutput = p.Direction != ParameterDirection.Input;
if ((input && isInput) || (!input && isOutput)) {
SqlStoredProcedure.TraceSource.TraceEvent(TraceEventType.Verbose, _eventId, "SqlParamter: Name = {0}, Value = '{1}', Type = {2}, Size = {3}", p.ParameterName, p.Value, p.DbType, p.Size);
}
}
}
}
protected void CloseOpenedConnection() {
if ((_command.Connection.State == ConnectionState.Open) & _connectionOpened)
_command.Connection.Close();
}
protected void TraceResult(string result) {
if (result != null) {
SqlStoredProcedure.TraceSource.TraceEvent(TraceEventType.Verbose, _eventId, "Result: {0}", result);
}
TraceParameters(false);
}
}
}
SqlStoredProcedure() is checking that there is a dot in your stored procedure name and if there isn't throwing that exception, so prefix your stored procedure name with "dbo." or whatever it is e.g.:
dbo.myProcedureName
It improves performance in the sense that SQL doesn't have to search all the users to find the proc first.
Related
My program can load in the listbox headers, but not the actually data from the whole table.
(how I am connecting to the database):
const string connectionString = "Data Source=test;Initial Catalog=dbi391731;User ID=test;Password=test";
SqlConnection conn = new SqlConnection(connectionString);
I'm using a class to load in the data:
public List<ScoreMdw> GetScoreMdwList()
{
List<ScoreMdw> scoremdwList = new List<ScoreMdw>();
conn.Open();
string query = ("Select employeeid, questionid, score from contentment");
SqlCommand cmd = new SqlCommand(query, conn);
try
{
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
ScoreMdw sm = new ScoreMdw((int)dr["employeeid"], (int)dr["questionid"], (char)dr["score"]);
scoremdwList.Add(sm);
}
}
}
catch (Exception ex)
{
Exception error = new Exception("error", ex);
throw error;
}
finally
{
conn.Close();
}
return scoremdwList;
}
In the while loop I'm using an other class:
class ScoreMdw
{
private int employeeid;
private int questionid;
private char score;
public ScoreMdw(int nr, int id, char s)
{
this.employeeid= nr;
this.questionid= id;
this.score = s;
}
public int EmployeeId
{
get { return employeeid; }
}
public int QuestionId
{
get { return questionid; }
}
public char Score
{
get { return score; }
}
public override string ToString()
{
string s = string.Format("{0} \t{1} \t{2}", this.employeeid, this.questionid, this.score);
return s;
}
}
In my main window I'm doing this:
private void btnLoadScores_Click(object sender, RoutedEventArgs e)
{
scoremdwList = new List<ScoreMdw>();
try
{
conn.Open();
List<string> headers = so.GetContentmentHeaders();
foreach (string header in headers)
txtHeader.Text += header + "\t";
scoremdwList = so.GetScoreMdwList();
lbScores.ItemsSource = scoremdwList;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
}
I get the error that I made in the class ("error"). I don't know what I'm doing wrong? Maybe something with the connection? Am I opening and closing it the wrong way?
May i ask you, to show us the ex.Message? So we know what the possible error could be.
try
{
using(SqlDataReader dr = cmd.ExecuteReader())
{
while(dr.read())
{
ScoreMdw sm = new ScoreMdw((int)dr["employeeid"], (int)dr["questionid"], (char)dr["score"]);
scoremdwList.Add(sm);
}
}
}
catch(Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message); // <= here you will get you errormessage that is important to fix your error.
Exception error = new Exception("error", ex);
throw error;
}
I have around 8-9 functions for filling tables from SQL to Sqlite and I am trying to make a dynamic function on which I will just pass some params and it will create the sqlite table (if it doesn't exist), create multiple instances in a loop of the type I want to insert in the specific table, set the properties for it and then insert it. Here are example functions:
private bool ReloadItemsFromServer()
{
try
{
using (GS.cnn)
{
SqlCommand command = new SqlCommand("rsp_FillItem_MobileDevice;", GS.cnn);
command.CommandType = System.Data.CommandType.StoredProcedure;
GS.cnn.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
string dbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "DataBase.PremierAndroid");
using (var sqliteConn = new SQLiteConnection(dbPath))
{
sqliteConn.CreateTable<Item>();
while (reader.Read())
{
{
var newItem = new Item();
newItem.ItemID = reader.GetInt32(0);
newItem.ItemBaseID = reader.GetInt32(1);
newItem.BrandID = reader.GetInt32(2);
newItem.Issue = reader.GetInt32(3);
sqliteConn.Insert(newItem);
}
}
}
}
else
{
_dlgAlert = new AlertDialog.Builder(this).Create();
_dlgAlert.SetMessage(Resources.GetString(Resource.String.NoRowsForItemFound));
_dlgAlert.SetTitle(Resources.GetString(Resource.String.Error));
_dlgAlert.SetButton("OK", delegate { });
_dlgAlert.Show();
return false;
}
reader.Close();
}
return true;
}
catch (Exception ex)
{
_dlgAlert = new AlertDialog.Builder(this).Create();
_dlgAlert.SetMessage(ex.Message);
_dlgAlert.SetTitle(Resources.GetString(Resource.String.Error));
_dlgAlert.SetButton("OK", delegate { });
_dlgAlert.Show();
return false;
}
finally
{
if (GS.cnn.State != ConnectionState.Closed)
{
GS.cnn.Close();
}
}
}
and here's another one:
private bool ReloadContragentsFromServer()
{
try
{
using (GS.cnn)
{
SqlCommand command = new SqlCommand("rsp_FillContragent_MobileDevice;", GS.cnn);
command.CommandType = System.Data.CommandType.StoredProcedure;
GS.cnn.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
string dbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "DataBase.PremierAndroid");
using (var sqliteConn = new SQLiteConnection(dbPath))
{
sqliteConn.CreateTable<Contragent>();
while (reader.Read())
{
{
var newContragent = new Contragent();
newContragent.ContragentID = reader.GetInt32(0);
newContragent.ContragentTypeID = reader.GetInt32(1);
newContragent.ContragentGroupID = reader.GetInt32(2);
newContragent.FullName = reader.GetString(3);
newContragent.BULSTAT = reader.GetString(4);
newContragent.ItemPriceGroupID = reader.GetInt32(5);
newContragent.ItemDiscountGroupID = reader.GetInt32(6);
sqliteConn.Insert(newContragent);
}
}
}
}
else
{
_dlgAlert = new AlertDialog.Builder(this).Create();
_dlgAlert.SetMessage(Resources.GetString(Resource.String.NoRowsForContragentFound));
_dlgAlert.SetTitle(Resources.GetString(Resource.String.Error));
_dlgAlert.SetButton("OK", delegate { });
_dlgAlert.Show();
return false;
}
reader.Close();
}
return true;
}
catch (Exception ex)
{
_dlgAlert = new AlertDialog.Builder(this).Create();
_dlgAlert.SetMessage(ex.Message);
_dlgAlert.SetTitle(Resources.GetString(Resource.String.Error));
_dlgAlert.SetButton("OK", delegate { });
_dlgAlert.Show();
return false;
}
finally
{
if (GS.cnn.State != ConnectionState.Closed)
{
GS.cnn.Close();
}
}
}
You can see what's different. How can I make it so I just call one method and give it some params so i dont have 8-9 blocks of code which are somewhat repeating?
I currently have this as a dynamic function (unfinished):
private bool LoadDataFromServer(string procedure, Type passedType)
{
try
{
using (GS.cnn)
{
SqlCommand command = new SqlCommand(procedure, GS.cnn);
command.CommandType = System.Data.CommandType.StoredProcedure;
GS.cnn.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
string dbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "DataBase.PremierAndroid");
using (var sqliteConn = new SQLiteConnection(dbPath))
{
sqliteConn.CreateTable(passedType);
while (reader.Read()) //to do > i++ bla bla
{
{
var newItem = Activator.CreateInstance(passedType);
//newItem - loop through properties and set = reader.get(int/string)(i)
sqliteConn.Insert(newItem);
}
}
}
}
else
{
_dlgAlert = new AlertDialog.Builder(this).Create();
_dlgAlert.SetMessage(Resources.GetString(Resource.String.NoRowsForItemFound));
_dlgAlert.SetTitle(Resources.GetString(Resource.String.Error));
_dlgAlert.SetButton("OK", delegate { });
_dlgAlert.Show();
return false;
}
reader.Close();
}
return true;
}
catch (Exception ex)
{
_dlgAlert = new AlertDialog.Builder(this).Create();
_dlgAlert.SetMessage(ex.Message);
_dlgAlert.SetTitle(Resources.GetString(Resource.String.Error));
_dlgAlert.SetButton("OK", delegate { });
_dlgAlert.Show();
return false;
}
finally
{
if (GS.cnn.State != ConnectionState.Closed)
{
GS.cnn.Close();
}
}
}
Thank you
let reflection and inherit help like this:
class Caller{
// see how it sends objects to method 'processAllClasses' with different classes
void main(){
ItemClass1 i1 = new ItemClass1();
i1.setItemsB(1,2);
processAllClasses(i1);
ItemClass2 i2 = new ItemClass2();
i2.setItemsB(10, 20);
processAllClasses(i2);
}
//using reflection and inherit to process different classes, obj is what need to be processed on.
//alternative way:
//get members from the type, then assign values to them one by one
void processAllClasses(ParentClass myobjvalue)
{
Type realtype = myobjvalue.GetType();
ParentClass myobj = new ParentClass();
MethodInfo mi = realtype.GetMethod("setItemsA");
object obj = Activator.CreateInstance(realtype);
Object[] parameter = new Object[] { myobjvalue };
mi.Invoke(obj, parameter);
}
}
class ParentClass {
}
class ItemClass1: ParentClass
{
int ItemID;
int ItemBaseID;
public void setItemsA(ItemClass1 itemclass1)
{
this.ItemID = itemclass1.ItemID;
this.ItemBaseID = itemclass1.ItemBaseID;
}
public void setItemsB(int ItemID, int ItemBaseID)
{
this.ItemID = ItemID;
this.ItemBaseID = ItemBaseID;
}
}
class ItemClass2 : ParentClass
{
int ContragentID;
int ContragentTypeID;
public void setItemsA(ItemClass2 itemclass2)
{
this.ContragentID = itemclass2.ContragentID;
this.ContragentTypeID = itemclass2.ContragentTypeID;
}
public void setItemsB(int ContragentID, int ContragentTypeID)
{
this.ContragentID = ContragentID;
this.ContragentTypeID = ContragentTypeID;
}
}
i Have a databasemanager class for accessing database and constants class which has database names and provider names. database and connectionstring works fine but provider name is null which raises an exception.
here is my code for databasemanager class
using System;
using System.Data;
/// <summary>
/// Summary description for ClsDataAccessLayer
/// </summary>
///
namespace MyAcademy.Forms
{
public class ClsDatabaseManager
{
#region [Member Variables]
private IDbConnection idbConnection;
private IDataReader idataReader;
private IDbCommand idbCommand;
private Constants.DataProvider providerType;
private IDbTransaction idbTransaction = null;
private IDbDataParameter[] idbParameters = null;
private string strConnection;
private string _ServerName;
private string _DatabaseName;
private string _UserID;
private string _Password;
private string _IntegratedSecurity;
#endregion
#region [Constructors]
public ClsDatabaseManager()
{
/*Default Constructor*/
ServerName = string.Empty;
DatabaseName = string.Empty;
UserID = string.Empty;
Password = string.Empty;
}
public ClsDatabaseManager(Constants.DataProvider providerType)
{
this.providerType = providerType;
}
public ClsDatabaseManager(Constants.DataProvider providerType, string
connectionString)
{
this.providerType = providerType;
this.strConnection = connectionString;
}
#endregion
public string ServerName
{
get { return _ServerName; }
set { _ServerName = value; }
}
public string DatabaseName
{
get { return _DatabaseName; }
set { _DatabaseName = value; }
}
public string UserID
{
get { return _UserID; }
set { _UserID = value; }
}
public string Password
{
get { return _Password; }
set { _Password = value; }
}
public string IntegratedSecurity
{
get { return _IntegratedSecurity; }
set { _IntegratedSecurity = value; }
}
private void SplitDatabaseConnectionString(string ConnectionString)
{
try
{
string[] ConParams = this.ConnectionString.Split(';');
foreach (string param in ConParams)
{
if (param.ToLower().Contains("database") || param.ToLower().Contains("initial catalog"))
{
DatabaseName = param;
DatabaseName = DatabaseName.Substring(DatabaseName.IndexOf('=') + 1, DatabaseName.Length - (DatabaseName.IndexOf('=') + 1)).Trim();
continue;
}
if (param.ToLower().Contains("data source") || param.ToLower().Contains("server"))
{
ServerName = param;
ServerName = ServerName.Substring(ServerName.IndexOf('=') + 1, ServerName.Length - (ServerName.IndexOf('=') + 1)).Trim();
continue;
}
if (param.ToLower().Contains("user") || param.ToLower().Contains("uid"))
{
UserID = param;
UserID = UserID.Substring(UserID.IndexOf('=') + 1, UserID.Length - (UserID.IndexOf('=') + 1)).Trim();
continue;
}
if (param.ToLower().Contains("password") || param.ToLower().Contains("pwd"))
{
Password = param;
Password = Password.Substring(Password.IndexOf('=') + 1, Password.Length - (Password.IndexOf('=') + 1)).Trim();
continue;
}
if (param.ToLower().Contains("integrated security"))
{
IntegratedSecurity = param;
IntegratedSecurity = IntegratedSecurity.Substring(IntegratedSecurity.IndexOf('=') + 1, IntegratedSecurity.Length - (IntegratedSecurity.IndexOf('=') + 1)).Trim();
continue;
}
}
}
catch { }
}
public static ClsDatabaseManager SplitDatabaseConnectionString(Constants.Databases eDatabase)
{
ClsDatabaseManager conString = new ClsDatabaseManager();
try
{
string str = null;
switch (eDatabase)
{
case Constants.Databases.Academy:
str = System.Configuration.ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
break;
case Constants.Databases.UniversityDB:
str = System.Configuration.ConfigurationManager.ConnectionStrings["UniversityDBCon"].ConnectionString;
break;
case Constants.Databases.HR_DB:
str = System.Configuration.ConfigurationManager.ConnectionStrings["HRMCon"].ConnectionString;
break;
case Constants.Databases.Inventory:
str = System.Configuration.ConfigurationManager.ConnectionStrings["Inventory"].ConnectionString;
break;
}
string[] arr1 = str.Split(';');
for (int i = 0; i < arr1.Length; i++)
{
string[] arr2 = arr1[i].Split('=');
switch (arr2[0])
{
case "Data Source":
conString.ServerName = arr2[1];
break;
case "Initial Catalog":
conString.DatabaseName = arr2[1];
break;
case "User ID":
conString.UserID = arr2[1];
break;
case "Password":
conString.Password = arr2[1];
break;
}
}
}
catch { }
return conString;
}
public static ClsDatabaseManager InitializeDbManager(Constants.Databases eDatabase = Constants.Databases.Academy)
{
string ConnectString = String.Empty;
switch (eDatabase)
{
case Constants.Databases.Academy:
try
{
ConnectString = Utility.Decrypt(System.Configuration.ConfigurationManager.ConnectionStrings["Connection"].ConnectionString);
}
catch
{
ConnectString = System.Configuration.ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
}
break;
case Constants.Databases.Account_DB:
try
{
ConnectString = Utility.Decrypt(System.Configuration.ConfigurationManager.ConnectionStrings["AccountDB"].ConnectionString);
}
catch
{
ConnectString = System.Configuration.ConfigurationManager.ConnectionStrings["AccountDB"].ConnectionString;
}
break;
case Constants.Databases.HR_DB:
try
{
ConnectString = Utility.Decrypt(System.Configuration.ConfigurationManager.ConnectionStrings["HRMCon"].ConnectionString);
}
catch
{
ConnectString = System.Configuration.ConfigurationManager.ConnectionStrings["HRMCon"].ConnectionString;
}
break;
case Constants.Databases.UniversityDB:
try
{
ConnectString = Utility.Decrypt(System.Configuration.ConfigurationManager.ConnectionStrings["UniversityDBCon"].ConnectionString);
}
catch
{
ConnectString = System.Configuration.ConfigurationManager.ConnectionStrings["UniversityDBCon"].ConnectionString;
}
break;
case Constants.Databases.Inventory:
try
{
ConnectString = Utility.Decrypt(System.Configuration.ConfigurationManager.ConnectionStrings["Inventory"].ConnectionString);
}
catch
{
ConnectString = System.Configuration.ConfigurationManager.ConnectionStrings["Inventory"].ConnectionString;
}
break;
}
string ProviderType = System.Configuration.ConfigurationManager.AppSettings["System.Data.SqlClient"];
Constants.DataProvider DP = (Constants.DataProvider)Enum.Parse(typeof(Constants.DataProvider), ProviderType);
ClsDatabaseManager dbManager = new ClsDatabaseManager(DP, ConnectString);
dbManager.SplitDatabaseConnectionString(ConnectString);
return dbManager;
}
#region [Properties]
public IDbConnection Connection
{
get
{
return idbConnection;
}
}
public IDataReader DataReader
{
get
{
return idataReader;
}
set
{
idataReader = value;
}
}
public Constants.DataProvider ProviderType
{
get
{
return providerType;
}
set
{
providerType = value;
}
}
public string ConnectionString
{
get
{
return strConnection;
}
set
{
strConnection = value;
}
}
public IDbCommand Command
{
get
{
return idbCommand;
}
}
public IDbTransaction Transaction
{
get
{
return idbTransaction;
}
}
public IDbDataParameter[] Parameters
{
get
{
return idbParameters;
}
}
#endregion
#region [Public Functions]
public void Open()
{
idbConnection =
ClsDatabaseManagerFactory.GetConnection(this.providerType);
idbConnection.ConnectionString = this.ConnectionString;
if (idbConnection.State != ConnectionState.Open)
idbConnection.Open();
this.idbCommand = ClsDatabaseManagerFactory.GetCommand(this.ProviderType);
}
public void Close()
{
if (idbConnection != null && idbConnection.State != ConnectionState.Closed)
idbConnection.Close();
}
public void Dispose()
{
GC.SuppressFinalize(this);
this.Close();
this.idbCommand = null;
this.idbTransaction = null;
this.idbConnection = null;
}
public void CreateParameters(int paramsCount)
{
idbParameters = new IDbDataParameter[paramsCount];
idbParameters = ClsDatabaseManagerFactory.GetParameters(this.ProviderType,
paramsCount);
}
public void AddParameters(int index, string paramName, object objValue, ParameterDirection direction = ParameterDirection.Input)
{
if (index < idbParameters.Length)
{
idbParameters[index].ParameterName = paramName;
idbParameters[index].Direction = direction;
idbParameters[index].Value = objValue;
}
}
public void AddParameters(int index, string paramName, object objValue, int size, ParameterDirection direction = ParameterDirection.Input)
{
if (index < idbParameters.Length)
{
idbParameters[index].ParameterName = paramName;
idbParameters[index].Direction = direction;
idbParameters[index].Value = objValue;
idbParameters[index].Size = size;
}
}
public void AddParameters(int index, string paramName, object objValue, DbType type, ParameterDirection direction = ParameterDirection.Input)
{
if (index < idbParameters.Length)
{
idbParameters[index].ParameterName = paramName;
idbParameters[index].Direction = direction;
idbParameters[index].Value = objValue;
idbParameters[index].DbType = type;
}
}
public void BeginTransaction()
{
if (this.idbTransaction == null)
idbTransaction = idbConnection.BeginTransaction();
//idbTransaction =
//ClsDatabaseManagerFactory.GetTransaction(this.ProviderType);
this.idbCommand.Transaction = idbTransaction;
}
public void BeginTransaction(IsolationLevel level)
{
if (this.idbTransaction == null)
idbTransaction = idbConnection.BeginTransaction(level);
//idbTransaction =
//ClsDatabaseManagerFactory.GetTransaction(this.ProviderType);
this.idbCommand.Transaction = idbTransaction;
}
public void CommitTransaction()
{
if (this.idbTransaction != null)
this.idbTransaction.Commit();
idbTransaction = null;
}
public void RollbackTransaction()
{
if (this.idbTransaction != null)
this.idbTransaction.Rollback();
idbTransaction = null;
}
public IDataReader ExecuteReader(string commandText, CommandType commandType = CommandType.StoredProcedure)
{
CloseReader();
this.idbCommand = ClsDatabaseManagerFactory.GetCommand(this.ProviderType);
idbCommand.Connection = this.Connection;
PrepareCommand(idbCommand, this.Connection, this.Transaction, commandType, commandText, this.Parameters);
this.DataReader = idbCommand.ExecuteReader();
idbCommand.Parameters.Clear();
return this.DataReader;
}
public void CloseReader()
{
if (this.DataReader != null && !this.DataReader.IsClosed)
this.DataReader.Close();
}
private void AttachParameters(IDbCommand command, IDbDataParameter[] commandParameters)
{
command.Parameters.Clear();
foreach (IDbDataParameter idbParameter in commandParameters)
{
if ((idbParameter.Direction == ParameterDirection.InputOutput)
&&
(idbParameter.Value == null))
{
idbParameter.Value = DBNull.Value;
}
command.Parameters.Add(idbParameter);
}
}
private void PrepareCommand(IDbCommand command, IDbConnection
connection,
IDbTransaction transaction, CommandType commandType, string
commandText,
IDbDataParameter[] commandParameters)
{
command.Connection = connection;
command.CommandText = commandText;
command.CommandType = commandType;
if (transaction != null)
{
command.Transaction = transaction;
}
if (commandParameters != null)
{
AttachParameters(command, commandParameters);
}
}
public int ExecuteNonQuery(string commandText, CommandType commandType = CommandType.StoredProcedure)
{
CloseReader();
this.idbCommand = ClsDatabaseManagerFactory.GetCommand(this.ProviderType);
PrepareCommand(idbCommand, this.Connection, this.Transaction,
commandType, commandText, this.Parameters);
int returnValue = idbCommand.ExecuteNonQuery();
idbCommand.Parameters.Clear();
return returnValue;
}
public object ExecuteScalar(string commandText, CommandType commandType = CommandType.StoredProcedure)
{
CloseReader();
this.idbCommand = ClsDatabaseManagerFactory.GetCommand(this.ProviderType);
PrepareCommand(idbCommand, this.Connection, this.Transaction,
commandType, commandText, this.Parameters);
object returnValue = idbCommand.ExecuteScalar();
idbCommand.Parameters.Clear();
return returnValue;
}
public DataSet ExecuteDataSet(string commandText, CommandType commandType = CommandType.StoredProcedure)
{
CloseReader();
this.idbCommand = ClsDatabaseManagerFactory.GetCommand(this.ProviderType);
PrepareCommand(idbCommand, this.Connection, this.Transaction, commandType,
commandText, this.Parameters);
IDbDataAdapter dataAdapter = ClsDatabaseManagerFactory.GetDataAdapter
(this.ProviderType);
dataAdapter.SelectCommand = idbCommand;
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
idbCommand.Parameters.Clear();
return dataSet;
}
public DataTable ExecuteDataTable(string commandText, CommandType commandType = CommandType.StoredProcedure)
{
DataSet ds = ExecuteDataSet(commandText, commandType);
if (ds != null && ds.Tables.Count > 0)
return ds.Tables[0];
else
return null;
}
#endregion
internal void CreatePerameter(int p)
{
throw new NotImplementedException();
}
}
}
and below is the constansts code
using System;
/// <summary>
/// Summary description for Constants
/// </summary>
namespace Constants
{
public enum DataProvider
{
Oracle = 1,
SqlServer = 2,
OleDb = 3,
Odbc = 4
}
public enum Databases
{
Academy = 1,
UniversityDB = 2,
Account_DB = 3,
HR_DB=4,
Inventory=5
}
}
You must convert the value to its string representation.
string ProviderType = System.Configuration.ConfigurationManager.AppSettings["System.Data.SqlClient"].ToString();
Above line should be like this
string ProviderType = System.Configuration.ConfigurationManager.AppSettings["connection"].ToString();
I'm having some problem with MySQL on a program. I'm not professional with it.
Error message:
"MySql.Data.MySqlClient.MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
at System.Void MySql.Data.MySqlClient.MySqlCommand.CheckState()
at MySqlDataReader MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(System.Data.CommandBehavior behavior)
at MySqlDataReader MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()"
The code is below:
public static class MySQL
{
private static string strConnection;
static void dbConnection_StateChange(object sender, StateChangeEventArgs ev)
{
if (ev.CurrentState == ConnectionState.Broken)
{
System.Threading.Thread.Sleep(1000);
dbConnection.Close();
}
if (ev.CurrentState == ConnectionState.Closed)
{
System.Threading.Thread.Sleep(1000);
dbConnection = new MySqlConnection(strConnection);
dbConnection.StateChange += new System.Data.StateChangeEventHandler(dbConnection_StateChange);
System.Threading.Thread.Sleep(1000);
dbConnection.Open();
}
}
private static MySqlConnection dbConnection;
public static bool openConnection(string dbHost, int dbPort, string dbName, string dbUsername, string dbPassword)
{
try
{
strConnection = "server=" + dbHost + ";" + "database=" + dbName + ";" + "uid=" + dbUsername + ";" + "password=" + dbPassword;
dbConnection = new MySqlConnection(strConnection);
dbConnection.StateChange += new System.Data.StateChangeEventHandler(dbConnection_StateChange);
dbConnection.Open();
Console.WriteLine(" Connected to MySQL.");
return true;
}
catch (Exception ex)
{
Console.WriteLine(" Couldn't connect to MySQL! The error:");
Console.WriteLine(ex.Message);
return false;
}
}
public static void closeConnection()
{
try
{
dbConnection.Close();
}
catch
{
Console.WriteLine("tasdsdaa fodaa");
}
}
public static void checkConnection()
{
try
{
if (dbConnection.State != ConnectionState.Open)
{
closeConnection();
openConnection(Config.dbHost, Config.dbPort, Config.dbName, Config.dbUsername, Config.dbPassword);
}
}
catch {
Console.WriteLine("ta fodaa");
}
}
public static void runQuery(string Query)
{
checkConnection();
try { new MySqlCommand(Query, dbConnection).ExecuteScalar(); }
catch { }
}
public static int insertGetLast(string Query)
{
checkConnection();
return int.Parse((new MySqlCommand(Query + "; SELECT LAST_INSERT_ID();", dbConnection).ExecuteScalar()).ToString());
}
public static string runRead(string Query)
{
checkConnection();
try { return new MySqlCommand(Query + " LIMIT 1", dbConnection).ExecuteScalar().ToString(); }
catch
{
return "";
}
}
public static int runRead(string Query, object Tick)
{
checkConnection();
try { return Convert.ToInt32(new MySqlCommand(Query + " LIMIT 1", dbConnection).ExecuteScalar()); }
catch
{
return 0;
}
}
public static string[] runReadColumn(string Query, int maxResults)
{
checkConnection();
MySqlCommand Command = null;
MySqlDataReader Reader = null;
if (maxResults > 0)
Query += " LIMIT " + maxResults;
try
{
Command = dbConnection.CreateCommand();
Command.CommandText = Query;
Reader = Command.ExecuteReader();
if (Reader.HasRows)
{
ArrayList columnBuilder = new ArrayList();
while (Reader.Read())
{
try { columnBuilder.Add(Reader[0].ToString()); }
catch { columnBuilder.Add(""); }
}
return (string[])columnBuilder.ToArray(typeof(string));
}
else
{
return new string[0];
}
}
catch(MySqlException Ex)
{
if (Command != null)
{
Console.WriteLine("[MySQL] Error!\n\r" + Command.CommandText, Ex);
}
else
{
Console.WriteLine("[MySQL] Error!", Ex);
}
}
finally
{
// Close the reader/command if they are active.
if (Reader != null)
{
Reader.Close();
Reader.Dispose();
}
if (Command != null)
{
Command.Dispose();
}
}
return new string[0];
}
public static int[] runReadColumn(string Query, int maxResults, object Tick)
{
checkConnection();
MySqlCommand Command = null;
MySqlDataReader Reader = null;
if (maxResults > 0)
Query += " LIMIT " + maxResults;
try
{
Command = dbConnection.CreateCommand();
Command.CommandText = Query;
Reader = Command.ExecuteReader();
if (Reader.HasRows)
{
ArrayList columnBuilder = new ArrayList();
while (Reader.Read())
{
try { columnBuilder.Add(Reader.GetInt32(0)); }
catch { columnBuilder.Add(0); }
}
return (int[])columnBuilder.ToArray(typeof(int));
}
else
{
return new int[0];
}
}
catch (MySqlException Ex)
{
if (Command != null)
{
Console.WriteLine("[MySQL] Error!\n\r" + Command.CommandText, Ex);
}
else
{
Console.WriteLine("[MySQL] Error!", Ex);
}
}
finally
{
// Close the reader/command if they are active.
if (Reader != null)
{
Reader.Close();
Reader.Dispose();
}
if (Command != null)
{
Command.Dispose();
}
}
return new int[0];
}
public static string[] runReadRow(string Query)
{
checkConnection();
MySqlCommand Command = null;
MySqlDataReader Reader = null;
try
{
Command = dbConnection.CreateCommand();
Command.CommandText = Query + " LIMIT 1";
Reader = Command.ExecuteReader();
if (Reader.HasRows)
{
ArrayList rowBuilder = new ArrayList();
while (Reader.Read())
{
for (int i = 0; i < Reader.FieldCount; i++)
{
try { rowBuilder.Add(Reader[i].ToString()); }
catch { rowBuilder.Add(""); }
}
}
return (string[])rowBuilder.ToArray(typeof(string));
}
else
{
return new string[0];
}
}
catch (MySqlException Ex)
{
if (Command != null)
{
Console.WriteLine("[MySQL] Error!\n\r" + Command.CommandText, Ex);
}
else
{
Console.WriteLine("[MySQL] Error!", Ex);
}
}
finally
{
// Close the reader/command if they are active.
if (Reader != null)
{
Reader.Close();
Reader.Dispose();
}
if (Command != null)
{
Command.Dispose();
}
}
return new string[0];
}
public static int[] runReadRow(string Query, object Tick)
{
checkConnection();
MySqlCommand Command = null;
MySqlDataReader Reader = null;
try
{
Command = dbConnection.CreateCommand();
Command.CommandText = Query + " LIMIT 1";
Reader = Command.ExecuteReader();
if (Reader.HasRows)
{
ArrayList rowBuilder = new ArrayList();
while (Reader.Read())
{
for (int i = 0; i < Reader.FieldCount; i++)
{
try { rowBuilder.Add(Reader.GetInt32(i)); }
catch { rowBuilder.Add(0); }
}
}
return (int[])rowBuilder.ToArray(typeof(int));
}
else
{
return new int[0];
}
}
catch (MySqlException Ex)
{
if (Command != null)
{
Console.WriteLine("[MySQL] Error!\n\r" + Command.CommandText, Ex);
}
else
{
Console.WriteLine("[MySQL] Error!", Ex);
}
}
finally
{
// Close the reader/command if they are active.
if (Reader != null)
{
Reader.Close();
Reader.Dispose();
}
if (Command != null)
{
Command.Dispose();
}
}
return new int[0];
}
public static bool checkExists(string Query)
{
checkConnection();
try { return new MySqlCommand(Query + " LIMIT 1", dbConnection).ExecuteReader().HasRows; }
catch
{
return false;
}
}
public static List<List<string>> readArray(string Query)
{
MySqlCommand Command = null;
MySqlDataReader Reader = null;
try
{
// Create the command.
Command = MySQL.dbConnection.CreateCommand();
Command.CommandText = Query;
// Read the result.
Reader = Command.ExecuteReader();
// Store the incomming fields.
List<List<string>> fieldValues = new List<List<string>>();
// Read all the data.
while (Reader.Read())
{
// Create a new field values to hold the data.
List<string> Buffer = new List<string>();
// Add the field values.
for (int i = 0; i < Reader.FieldCount; i++)
{
Buffer.Add(Reader[i].ToString());
}
// Add it too our overall data.
fieldValues.Add(Buffer);
}
return fieldValues;
}
catch (MySqlException Ex)
{
if (Command != null)
{
Console.WriteLine("[MySQL] Error!\n\r" + Command.CommandText, Ex);
}
else
{
Console.WriteLine("[MySQL] Error!", Ex);
}
return null;
}
finally
{
// Close the reader/command if they are active.
if (Reader != null)
{
Reader.Close();
Reader.Dispose();
}
if (Command != null)
{
Command.Dispose();
}
}
}
public static string Stripslash(string Query)
{
try { return Query.Replace(#"\", "\\").Replace("'", #"\'"); }
catch { return ""; }
}
}
You need to call Close on your Reader objects to release the underline resources, something like this:
try
{
Command = dbConnection.CreateCommand();
Command.CommandText = Query;
using (Reader = Command.ExecuteReader()) // 'using' forces a call to `Dispose`/`Close` at the end of the block
{
if (Reader.HasRows)
{
ArrayList columnBuilder = new ArrayList();
while (Reader.Read())
{
try { columnBuilder.Add(Reader.GetInt32(0)); }
catch { columnBuilder.Add(0); }
}
return (int[])columnBuilder.ToArray(typeof(int));
}
else
{
return new int[0];
}
}
}
an obvious issue to me is here:
public static bool checkExists(string Query)
{
checkConnection();
try { return new MySqlCommand(Query + " LIMIT 1", dbConnection).ExecuteReader().HasRows; }
catch
{
return false;
}
}
You aren't closing the reader here, LEAK.
How would one go about using Dapper with Oracle stored procedures which return cursors?
var p = new DynamicParameters();
p.Add("foo", "bar");
p.Add("baz_cursor", dbType: DbType.? , direction: ParameterDirection.Output);
Here, the DbType is System.Data.DbType which does not have a Cursor member. I've tried using DbType.Object but that does not work with both OracleClient and OracleDataAcess.
What would be a possible way to use OracleType or OracleDbType instead?
Thanks for the solution here. I achieved the same thing with a little less code using a simple DynamicParameter decorator:
public class OracleDynamicParameters : SqlMapper.IDynamicParameters
{
private readonly DynamicParameters dynamicParameters = new DynamicParameters();
private readonly List<OracleParameter> oracleParameters = new List<OracleParameter>();
public void Add(string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null)
{
dynamicParameters.Add(name, value, dbType, direction, size);
}
public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction)
{
var oracleParameter = new OracleParameter(name, oracleDbType, direction);
oracleParameters.Add(oracleParameter);
}
public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
((SqlMapper.IDynamicParameters)dynamicParameters).AddParameters(command, identity);
var oracleCommand = command as OracleCommand;
if (oracleCommand != null)
{
oracleCommand.Parameters.AddRange(oracleParameters.ToArray());
}
}
}
You would have to implement:
public interface IDynamicParameters
{
void AddParameters(IDbCommand command, Identity identity);
}
Then in the AddParameters callback you would cast the IDbCommand to an OracleCommand and add the DB specific params.
Add this class to your project
and your code should like below :-
var p = new OracleDynamicParameters();
p.Add("param1", pAuditType);
p.Add("param2", pCommnId);
p.Add("outCursor", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
using (var multi = cnn.QueryMultiple("procedure_name", param: p, commandType: CommandType.StoredProcedure))
{
var data = multi.Read();
return data;
}
Just to elaborate on Sams suggestion here's what I came up with. Note that this code is brittle and is now just for Oracle.
Modified Dapper 1.7
void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
if (templates != null)
{
foreach (var template in templates)
{
var newIdent = identity.ForDynamicParameters(template.GetType());
Action<IDbCommand, object> appender;
lock (paramReaderCache)
{
if (!paramReaderCache.TryGetValue(newIdent, out appender))
{
appender = SqlMapper.CreateParamInfoGenerator(newIdent);
paramReaderCache[newIdent] = appender;
}
}
appender(command, template);
}
}
foreach (var param in parameters.Values)
{
string name = Clean(param.Name);
bool add = !((Oracle.DataAccess.Client.OracleCommand)command).Parameters.Contains(name);
Oracle.DataAccess.Client.OracleParameter p;
if(add)
{
p = ((Oracle.DataAccess.Client.OracleCommand)command).CreateParameter();
p.ParameterName = name;
} else
{
p = ((Oracle.DataAccess.Client.OracleCommand)command).Parameters[name];
}
var val = param.Value;
p.Value = val ?? DBNull.Value;
p.Direction = param.ParameterDirection;
var s = val as string;
if (s != null)
{
if (s.Length <= 4000)
{
p.Size = 4000;
}
}
if (param.Size != null)
{
p.Size = param.Size.Value;
}
if (param.DbType != null)
{
p.DbType = param.DbType.Value;
}
if (add)
{
if (param.DbType != null && param.DbType == DbType.Object)
{
p.OracleDbType = Oracle.DataAccess.Client.OracleDbType.RefCursor;
((Oracle.DataAccess.Client.OracleCommand)command).Parameters.Add(p);
}
else
{
((Oracle.DataAccess.Client.OracleCommand)command).Parameters.Add(p);
}
}
param.AttachedParam = p;
}
}
Test code
class Program
{
static void Main(string[] args)
{
OracleConnection conn = null;
try
{
const string connString = "DATA SOURCE=XE;PERSIST SECURITY INFO=True;USER ID=HR;PASSWORD=Adv41722";
conn = new OracleConnection(connString);
conn.Open();
var p = new DynamicParameters();
p.Add(":dep_id", 60);
p.Add(":employees_c", dbType: DbType.Object, direction: ParameterDirection.Output);
p.Add(":departments_c", dbType: DbType.Object, direction: ParameterDirection.Output);
// This will return an IEnumerable<Employee> // How do I return both result?
var results = conn.Query<Employee>("HR_DATA.GETCURSORS", p, commandType: CommandType.StoredProcedure);
}
catch (Exception exception)
{
Console.WriteLine(exception);
throw;
}
finally
{
if (conn != null && conn.State == ConnectionState.Open)
{
conn.Close();
}
}
Console.WriteLine("Fininhed!");
Console.ReadLine();
}
}
class Employee
{
public int Employee_ID { get; set; }
public string FIRST_NAME { get; set; }
public string LAST_NAME { get; set; }
public string EMAIL { get; set; }
public string PHONE_NUMBER { get; set; }
}