Fill: SelectCommand.Connection property has not been initialized - c#

After a while using the website, loading contents, etc.. this message shows "Fill: SelectCommand.Connection property has not been initialized"!
I think this is because the sql connection, but not sure... I'd like to know what can i do to prevent this, every time this happens i have to upload a file (SQL class, that make the connection) and the website starts to work again.
My SQL connection:
public class SQL
{
SqlCommand comandos;
public SqlConnection sql()
{
string Server = #"server";
string Username = "user";
string Password = "pass";
string Database = "database";
string ConnectionString = "Data Source=" + Server + ";";
ConnectionString += "User ID=" + Username + ";";
ConnectionString += "Password=" + Password + ";";
ConnectionString += "Initial Catalog=" + Database;
SqlConnection Connection = new SqlConnection();
try
{
Connection.ConnectionString = ConnectionString;
Connection.Open();
return Connection;
}
catch (Exception)
{
if (Connection != null)
{
Connection.Dispose();
}
return null;
}
}
public void FazerComando(string comando)
{
comandos = new SqlCommand(comando, sql());
comandos.ExecuteNonQuery();
}
public DataTable Execute(string comando)
{
SqlDataAdapter SQLDataAdapter = new SqlDataAdapter(comando, sql());
DataTable dtResult = new DataTable();
SQLDataAdapter.Fill(dtResult);
return dtResult;
}
}

This might be related to your problem, but in any case, it's something that should be addressed: You're not disposing your connections when you're done with them. You should use using:
public void FazerComando(string comando)
{
using (var conn = sql())
{
comandos = new SqlCommand(comando, conn);
comandos.ExecuteNonQuery();
}
}
public DataTable Execute(string comando)
{
using (var conn = sql())
{
SqlDataAdapter SQLDataAdapter = new SqlDataAdapter(comando, conn);
DataTable dtResult = new DataTable();
SQLDataAdapter.Fill(dtResult);
return dtResult;
}
}

I've never taken that approach before. We usually just use the connection string in web config, expecially with linq, it works very well. I suggest you have a look at http://blogs.msdn.com/b/visualstudio/archive/2012/06/11/world-of-samples-at-your-fingertips.aspx and follow the trail. You should find a good example of a recommended best practice for connections. The connection string will then be read at the first lauch of your app, and connection pooling (v imortant) used to best effect.
Oh and you are not disposing of your connection, which will cause a memory leek and iis to clear out your app pool when the memeory usage becomes too large -- all v bad
As the other respondant says whilst I was looking up the baet prac link...
HTH

Related

C# sending select command from one class to another and return result?

I am beginner in C#, so this question may be a bit stupid but...
I would like to send some SQL command as string from one class to another, execute and then return result to the first class.
class MainWindow
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
TestConnection checkLogin = new TestConnection();
checkLogin.SimpleQuery("SELECT Name FROM Names WHERE ID='1'", "");
//MessageBox .Show(checkLogin.SimpleQuery(response:ToString));
}
And class TestConnection
public string SimpleQuery(string request, string response)
{
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = "Server=SQLOLEDB.1;User ID=" +
Constants.DATABASE_USERNAME + ";Password=" +
Constants.DATABASE_PASSWORD + ";Initial Catalog=" +
Constants.DATABASE_CATALOG + ";Data Source=" +
Constants.SERVER_ADRESS;
SqlCommand command = new SqlCommand(request, conn);
{
conn.Open();
response = Convert.ToString (command.ExecuteScalar());
conn.Close();
return response;
}
}
Is something like this even an OK idea?
I am learning and I am testing ideas..
Thank you!
The thing is, usually you want your classes to encapsulate functionality.
In your case, it makes more sense if you keep the query in the object and expose a method which name correspond with the actual functionality, e.g.:
//your class, also: the name must describe it's reason for existence
public class UserRepository { //previously known as TestConnection
//the method name explains its function.
//the query is stored within the function
//therefore the functionality is encapsulated
public string CheckLogin(int id)
{
//note: tricky: almost SQL injection here: that must be fixed.
//I just left it here so you can see the basic idea
var request = "SELECT Name FROM Names WHERE ID =" + id.ToString();
//another note: response doesn't have to be passed as parameter.
var response = string.Empty;
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = "Server=SQLOLEDB.1;User ID=" +
Constants.DATABASE_USERNAME + ";Password=" +
Constants.DATABASE_PASSWORD + ";Initial Catalog=" +
Constants.DATABASE_CATALOG + ";Data Source=" +
Constants.SERVER_ADRESS;
SqlCommand command = new SqlCommand(request, conn);
{
conn.Open();
response = Convert.ToString (command.ExecuteScalar());
conn.Close();
return response;
}
}
There are some further enhancements which can be made, but for now I think this will give you enough to think about.
SQL injection issue (see comment)
To prevent SQL injection, a good approach is to use parameters. There is an article about it here.
Basically it come down on using parameterized inputs:
disclaimer: copied from link:
using (SqlCommand command =
new SqlCommand("SELECT * FROM Dogs1 WHERE Name LIKE #Name", connection))
{
// Add new SqlParameter to the command.
command.Parameters.Add(new SqlParameter("Name", dogName));
For more information about how and why, see this link.
Here is a working example with fixes for the non parameterized sql and suggestions on how to better store the connection string.
MainWindow.cs
class MainWindow
{
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
SomeRepository repo = new SomeRepository();
var userName = repo.GetUserName(1);
MessageBox.Show(userName ?? "User not found!");
}
}
SomeRepository.cs
public sealed class SomeRepository
{
private readonly string connectionString;
public SomeRepository()
{
// the ideal location for a connection string is in the application's app.config (or web.confic)
connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
// Or uncomment this
// connectionString = "Server=SQLOLEDB.1;User ID=" +
// Constants.DATABASE_USERNAME + ";Password=" +
// Constants.DATABASE_PASSWORD + ";Initial Catalog=" +
// Constants.DATABASE_CATALOG + ";Data Source=" +
// Constants.SERVER_ADRESS;
}
public string GetUserName(int id)
{
const string sqlRequest = "SELECT Name FROM Names WHERE ID = #id";
using (SqlConnection conn = new SqlConnection(this.connectionString))
using (SqlCommand command = new SqlCommand(sqlRequest, conn))
{
// if this is an integer in the schema, which it looks like it should be, then you need to pass it as an int and not a string
command.Parameters.Add("#id", SqlDbType.Int).Value = id;
// if it is a string then specify the type as varchar and specify the varchar length in the schema and pass a string
// command.Parameters.Add("#id", SqlDbType.VarChar, 20).Value = id.ToString();
conn.Open();
return command.ExecuteScalar()?.ToString();
}
}
}
app.config
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="MyConnection" connectionString="YOUR CONNECTION STRING HERE" providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
You have to store your return result from SimpleQuery() to finally show this in a MessageBox.
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
TestConnection checkLogin = new TestConnection();
string result = checkLogin.SimpleQuery("SELECT Name FROM Names WHERE ID='1'", "");
MessageBox.Show(result);
}
Alter your method to return the result:
public string SimpleQuery(string request, string response)
{
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = "Server=SQLOLEDB.1;User ID=" +
Constants.DATABASE_USERNAME + ";Password=" +
Constants.DATABASE_PASSWORD + ";Initial Catalog=" +
Constants.DATABASE_CATALOG + ";Data Source=" +
Constants.SERVER_ADRESS;
SqlCommand command = new SqlCommand(request, conn);
conn.Open();
string response = Convert.ToString(command.ExecuteScalar());
conn.Close();
return response;
}
}

Run SQL script from ASP.Net C# application performance issue

I'm running SQL script from C# code, my problem that the code take a long time to finish execution, it has many tables to be created in script(at least 30 Tables), so my code is working but it has performance issue.
this is the code
public static bool executeSqlScript(string scriptPath,string serverName,string databaseName)
{
try
{
SqlConnection myConn = new SqlConnection("Server=.;Integrated security=SSPI;database=master");
Server server = new Server(new ServerConnection(myConn));
string CreateCommand = "CREATE DATABASE " + databaseName + "";
string appendText;
//delete first line from script(Oldscript)
var lines = File.ReadAllLines(scriptPath).Skip(1);
File.WriteAllLines(scriptPath, lines);
using (StreamReader sreader = new StreamReader(scriptPath))
{
appendText = sreader.ReadToEnd();
}
File.Delete(scriptPath);
using (StreamWriter swriter = new StreamWriter(scriptPath, false))
{
appendText = "USE [" + databaseName + "]" + Environment.NewLine + appendText;
swriter.Write(appendText);
swriter.Close();
}
string readtext = File.ReadAllText(scriptPath);
SqlCommand myCommand = new SqlCommand(CreateCommand, myConn);
myConn.Open();
myCommand.ExecuteNonQuery();
server.ConnectionContext.ExecuteNonQuery(readtext);
return true;
}
catch (Exception e)
{
throw e;
return false;
}
}
My recommendation would be to migrate most of this to the SQL Server, once the new DB and User are setup, call a Stored Procedure to read the SQL file with the necessary DDL in it.
My last project was for a managed hosting company, and our CMS utilized well over 150 database objects. We used a "control" database which we pass in the new DB information and it would ceate the new tables, functions, and procedures generally in less than a minute.
use Parallel.ForEach to create tables likes
public static bool executeSqlScript(string scriptPath, string serverName, string databaseName)
{
try
{
SqlConnection myConn = new SqlConnection("Server=.;Integrated security=SSPI;database=master");
//Server server = new Server(new ServerConnection(myConn));
string CreateCommand = "CREATE DATABASE " + databaseName + "";
string appendText;
//delete first line from script(Oldscript)
//create db first
var myCommand = new SqlCommand(CreateCommand, myConn);
myConn.Open();
myCommand.ExecuteNonQuery();
myConn.Close();
List<string[]> list = File.ReadLines(scriptPath)
.Select(line => line.ToLower().Split(new string[] { "go" }, StringSplitOptions.None))
.ToList();
Parallel.ForEach(list, (sql) =>
{
using (var mysqlConn = new SqlConnection("Server=.;Integrated security=SSPI;database=master"))
{
var mysql = "USE [" + databaseName + "]" + Environment.NewLine + string.Join("", sql);
var mysqlCommand = new SqlCommand(mysql, mysqlConn);
myConn.Open();
mysqlCommand.ExecuteNonQuery();
}
});
//server.ConnectionContext.ExecuteNonQuery(readtext);
return true;
}
catch (Exception e)
{
throw e;
return false;
}
}
The problem was in Go Keyword in script, I Found this solution
http://www.codingdefined.com/2014/07/run-sql-script-file-in-c.html
(If you are trying to execute a SQL generated script file you have to remove all "GO". For that you have to use the following code...)
Here is my code:
string sqlConnectionString = "Data Source=.;Initial Catalog=master;Integrated Security=True";
FileInfo file = new FileInfo(#"D:\Script.sql");
string script = file.OpenText().ReadToEnd();
SqlConnection conn = new SqlConnection(sqlConnectionString);
conn.Open();
script = script.Replace("GO", "");
SqlCommand cmd = new SqlCommand(script, conn);
cmd.ExecuteNonQuery();
cmd.Dispose();
conn.Close();

Database connection with c# using access

I want to connect to my MS Access database from c# and I am getting the following error:
unrecognized database format 'data.accdb'
What should I do? Please help
Use connection string like this:
public static string ConStr = "Provider=Microsoft.ACE.Oledb.15.0; Data Source=D:\db.accdb;";
public static void DeleteTable(string TableName)
{
OleDbConnection connection = new OleDbConnection(OLEDB.ConStr);
OleDbCommand oleDbCommand = new OleDbCommand(string.Format("delete from [{0}]", (object) TableName), connection);
try
{
connection.Open();
oleDbCommand.ExecuteNonQuery();
}
catch
{
}
finally
{
connection.Close();
}
}
I made a class for that. It works perfectly with the latest visual studio, or vs 2010 with access 2010. If you have a newer version of access you need to install the Access Database Engine. It also contains a function that strips the apostrofe preventing your sql being hacked using sql injection and a method for creating md5 hashes.
using System.Data;
using System.Data.OleDb;
using System.Text;
using System.Security.Cryptography;
public class Database
{
#region Variables
String Name;
String Path;
String ConnectionString;
OleDbConnection Connection;
#endregion
#region Init Destroy
public Database(String Name)
{
this.Name = #"App_Data\" + Name;
Path = HttpContext.Current.Server.MapPath(this.Name);
ConnectionString = #"Provider = Microsoft.ACE.OLEDB.12.0; " +
"Data Source = " + Path + ";" +
"Persist Security Info = False;";
Connection = new OleDbConnection(ConnectionString);
if (Connection.State == System.Data.ConnectionState.Closed)
{
Connection.Open();
}
}
public void finalize()
{
if (Connection.State == System.Data.ConnectionState.Open)
{
try { Connection.Close(); }
catch { }
}
}
#endregion
#region Queries
public void execute(String query)
{
OleDbCommand command = new OleDbCommand(query, Connection);
command.ExecuteNonQuery();
}
public OleDbDataReader select(String query)
{
OleDbCommand command = new OleDbCommand(query, Connection);
OleDbDataReader data = command.ExecuteReader();
return data;
}
public DataSet selectData(String query)
{
OleDbCommand command = new OleDbCommand(query, Connection);
OleDbDataAdapter adp = new OleDbDataAdapter(command);
DataSet ds = new DataSet();
adp.Fill(ds);
return ds;
}
public object scalar(String query)
{
OleDbCommand command = new OleDbCommand(query, Connection);
object data = new object();
data = command.ExecuteScalar();
return data;
}
#endregion
#region Encryption Security
public String stripInjection(String field)
{
String x = field.Replace(#"'", string.Empty);
x = x.Replace(#"""", string.Empty);
return x;
}
public string md5Hash(string input)
{
StringBuilder hash = new StringBuilder();
MD5CryptoServiceProvider md5provider = new MD5CryptoServiceProvider();
byte[] bytes = md5provider.ComputeHash(new UTF8Encoding().GetBytes(input));
for (int i = 0; i < bytes.Length; i++)
{
hash.Append(bytes[i].ToString("x2"));
}
return hash.ToString().ToUpper();
}
#endregion
}
Don't put finalize instructions in the destructor of the class (As Microsoft says in the documentation because it will launch some exceptions). Just call it when you have finished your tasks:
Database database = new Database("data.accdb");
DataSet result = database.selectData("SELECT something FROM table WHERE condition;");
database.finalize();
Copy Your Databse file .accdb in Debug folder of project then add app.config file in your project
Write below code in app.config in Configuration tag
<connectionStrings>
<add name="db" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\sse_db.accdb;Persist Security Info=False;"
providerName="System.Data.Oledb" />
</connectionStrings>
1)Add System.Configuration Reference
Use connection object as follows
OleDbConnection con = new OleDbConnection(System.Configuration.ConfigurationManager.ConnectionStrings["db"].ConnectionString);

How to kill a SQL Server session or session ID

I'm trying to kill a session in SQL Server 2012 from C# windows Form using kill <spid> but what happens is that when I do that, an error appears:
Cannot use KILL to kill your own process
Code:
// to do DB backup
private void spid2_Click(object sender, EventArgs e)
{
string SQLDataBases;
SQLDataBases = "select ##spid ";
SQLDataBases += "BACKUP DATABASE School TO DISK = \'C:\\Program Files\\Microsoft SQL Server\\MSSQL11.MSSQLSERVER\\MSSQL\\Backup\\AdventureWorks333.BAK\' ";
string svr = "Server=" + localsrv + ";Initial Catalog=master;Integrated Security = SSPI;";
SqlConnection cnBk = new SqlConnection(svr);
Command = new SqlCommand(SQLDataBases, cnBk);
Command.CommandText = SQLDataBases;
SqlDataAdapter da = new SqlDataAdapter(Command);
DataTable dtDatabases = new DataTable();
try
{
cnBk.Open();
da.Fill(dtDatabases);
label1.Text = dtDatabases.Rows[0][0].ToString();
}
catch (Exception ex)
{
string s = ex.ToString();
MessageBox.Show(s);
label1.Text = dtDatabases.Rows[0][0].ToString();
}
finally
{
if (cnBk.State == ConnectionState.Open)
{
cnBk.Close();
cnBk.Dispose();
}
}
}
// to kill backup session
private void kill_Click(object sender, EventArgs e)
{
string SQLRestor;
SQLRestor = "Use master; kill " + label1.Text;
string svr = "Server=" + localsrv + ";Initial Catalog=master;Integrated Security = SSPI;";
SqlConnection cnRestore = new SqlConnection(svr);
SqlCommand cmdBkUp = new SqlCommand(SQLRestor, cnRestore);
try
{
cnRestore.Open();
cmdBkUp.ExecuteNonQuery();
}
catch (Exception ex)
{
string s = ex.ToString();
}
finally
{
if (cnRestore.State == ConnectionState.Open)
{
cnRestore.Close();
cnRestore.Dispose();
}
}
}
Always use "using" for disposable classes (also to close and dispose), never concatenate string in query, use always parameterized query to avoid sql injection. This is sample how to use SqlConnection, SqlDataAdapter, and SqlCommand :
var connectionString = "...";
var sqlQuery = "...";
// Sample using SqlCommand
try
{
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
using (var cmd = new SqlCommand(sqlQuery, conn))
{
cmd.ExecuteNonQuery();
}
}
MessageBox.Show("OK, SqlConnection and SqlCommand are closed and disposed properly");
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex);
}
// Sample using SqlDataAdapter
try
{
var dataTable = new DataTable();
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
using (var sda = new SqlDataAdapter(sqlQuery, conn))
{
sda.Fill(dataTable);
}
}
MessageBox.Show("OK, SqlConnection and SqlDataAdapter are closed and disposed properly, use DataTable here...");
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex);
}
The "Cannot use KILL to kill your own process" is there for a reason. If you're finished using your session, close the connection: SqlConnection is an IDisposable, so wrapping it in an using() {} block will close it automatically when you're done using it. This will return the connection handle back to the pool, and it is up to the SQL server client components to decide whether to keep it around for follow-up connections, or dispose it. SQL server does a good job of managing its process lifecycle and killing them is an administrative option, but nothing that an application in normal operation should do (except for a few reasons, see here)
That said, to answer the actual question: to kill process A, you'd have to open a second connection B and KILL A's process (SPID). This will work as long as the assumption "one SPID = one connection = one session" holds (true for all current SQL server versions).
Furthermore, your user needs the ALTER ANY CONNECTION privilege. This is usually limited to sysadmin and processadmin roles, and your application is unlikely to have this in a production environment.
References:
http://www.sqlservercentral.com/Forums/Topic1503836-1292-1.aspx
http://sqlserverplanet.com/dba/spid-what-is-it

C# database connection class not working

Im following a C# database connection tutorial however the code they provide for the connection class has a problem, it has an error on dat_set which I'm assuming needs to be set as a variable but I'm unsure. Having looked at the code the tutorial provides many times what i have is exactly the same
The errors are these lines
da_1.Fill(dat_set, "Table_Data_1");
return dat_set;
Here is what i have
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data;
namespace JBT
{
class DBConnect
{
private string sqlString;
private string strCon;
System.Data.SqlClient.SqlDataAdapter da_1;
public string Sql
{
set { sqlString = value; }
}
public string connection_string
{
set { strCon = value; }
}
public System.Data.DataSet GetConnection
{
get
{ return MyDataSet(); }
}
private System.Data.DataSet MyDataSet()
{
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(strCon);
con.Open();
da_1 = new System.Data.SqlClient.SqlDataAdapter(sqlString, con);
da_1.Fill(dat_set, "Table_Data_1");
con.Close();
return dat_set;
}
}
}
The Dataset that you want to Fill need to be intialized before
private System.Data.DataSet MyDataSet()
{
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(strCon);
con.Open();
da_1 = new System.Data.SqlClient.SqlDataAdapter(sqlString, con);
System.Data.DataSet dat_set = new System.Data.DataSet();
da_1.Fill(dat_set, "Table_Data_1");
con.Close();
return dat_set;
}
Of course this could work only if you have initialized the sqlString and the strCon before calling this code. This should be assumed because you say that the error occurs at the Fill line
The
System.Data.DataSet MyDataSet() is not what you have to put in your code if you are using Mysql
first initialize the code.
then write methods to open and close connection.
now you are ready for the db connection.
public class DbConnection
{
private MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
private void initialize()
{
server = "localhost";
database = "yourdatabase";
uid = "root";
password = "";
string connectionString = "server=" + server + ";database=" + database + ";uid=" + uid + ";password=" + password + ";";
connection = new MySqlConnection(connectionString);
}
//open connection
private bool openConnection()
{
try
{
connection.Open();
return true;
}
catch(MySqlException ex)
{
switch(ex.Number)
{
case 0:
MessageBox.Show("Cannot connect to server. Contact administrator");
break;
case 1045:
MessageBox.Show("Invalid username/password, please try again");
break;
}
return false;
}
}
if you want to develop complete db connection use this site: http://www.codeproject.com/Articles/43438/Connect-C-to-MySQL
helped me a lot :)

Categories

Resources