The error with ExecuteReader: Connection property has not been initialized is giving me a fit. I think I have it set up right. I will show you how I create the mssql connection and then what I am requesting, and the class I created to read/write and open/close the connection. (Three different parts of the app but I just lumped them together so you could see the actual logic flow I hope.)
What am I missing, or where am I supposed to put the connection? Example? I appreciate the help!
Here is the using statement I start with:
using (MSSQL mssqldb = new MSSQL(Constants.msSqlServer, Constants.msSqlDb, Constants.msSqlUid, Constants.msSqlPswd))
Here is where I say "Hey, get me my data using my MSSQL class"
using (var results = mssqldb.Read("SELECT TOP 1 * FROM AlertLog ORDER BY AlarmID DESC"))
{
results.Read();
legacyAlert = Int32.Parse(results["AlarmId"].ToString().Trim());
}
Here is the MSSQL class
class MSSQL : IDisposable
{
public MSSQL(string server, string database, string uid, string pswd)
{
string msSqlConnectionString = #"Data Source=" + server + ";Initial Catalog=" + database + ";user id=" + uid + ";password=" + pswd;
SqlConnection msqlConnection = new SqlConnection(msSqlConnectionString);
msqlConnection.Open();
Console.WriteLine("MS SQL OPEN!");
}
public void Write(string sql)
{
using (SqlCommand myCommand = new SqlCommand(sql, msqlConnection))
myCommand.ExecuteNonQuery();
}
public SqlDataReader Read(string sql)
{
using (SqlCommand myCommand = new SqlCommand(sql, msqlConnection))
return myCommand.ExecuteReader();
}
public void Dispose()
{
try {
msqlConnection.Close();
}
catch (SqlException ex) {
Console.Error.WriteLine("MS SQL Error - Closing Database");
Console.Error.WriteLine(ex);
}
msqlConnection.Dispose();
}
private SqlConnection msqlConnection;
}
msqlConnection is null.
Your constructor creates a local variable named msqlConnection, but does not assign to the field.
Related
Through the information I have found searching here on stackoverflow, I have what I think is 90% of this solved but because of how OleDbConnection is converted to define SqlConnection, the call to the class with the connection and test script wants definition I am unsure how to provide.
I've used these pages to get what I have so far
How to create an SqlConnection in C# to point to UDL file
Calling an SQL Connection method in C#
private static string CONNECTION_NAME = #"C:\Temp\DisplayDB.udl";
public static class MyConnection
{
public static SqlConnection GetSqlConnection()
{
var udlInfo = new OleDbConnection($"File Name={CONNECTION_NAME}");
return CreateSqlConnection(udlInfo);
}
public static SqlConnection CreateSqlConnection(OleDbConnection udlInfo)
{
try
{
string CONNECTION_STRING = $"Database={udlInfo.Database};Server={udlInfo.DataSource};User ID=User;Password=13245;Integrated Security=True;connect timeout = 30";
var connection = new SqlConnection(CONNECTION_STRING);
connection.Open();
return connection;
}
catch
{
Console.WriteLine($"{CONNECTION_NAME} Not found");
return null;
}
}
}
private void DBCheck()
{
// The line below is my issue, mouseover error of ".CreateSqlConnection"
// says there is no argument given that corresponds to the required
// formal parameter 'udlInfo' of
// 'MainWindow.MyConnection.CreateSqlConnection(OleDbConnection)'
using (var con = MyConnection.CreateSqlConnection())
{
con.Open();
var command = new SqlCommand("IF DB_ID ('CodeTest') IS NULL " +
"BEGIN " +
"USE MASTER " +
"CREATE DATABASE CodeTest" +
" END", con);
var reader = command.ExecuteReader();
reader.Close();
con.Close();
}
}
I expect the WPF to use the Database and Server from the UDL file to make the SqlConnection so I can run queries and commands. I understand the security part of UDL in plain text but I do not want hard coded values as this application will be used in various environments nor do I want those values to need definition on each launch of the app.
I am new to C# and need help with creating a class, which can be called in every newly created class and return connection to database. There is what I have done so far:
using System;
using MySql.Data.MySqlClient;
namespace SqlQueries
{
class DBConnect
{
public static void Main()
{
//Initialize();
}
private static MySqlConnection connection;
private static string server;
private static string database;
private static string uid;
private static string password;
public static void Initialize()
{
server = "testing.com";
database = "mus_le";
uid = "muff";
password = "test";
string connectionString = "Server=" + server + ";"+"Database=" + database + ";" + "Uid=" + uid + ";" + "Password=" + password + ";";
using (connection = new MySqlConnection(connectionString))
{
connection.Open();
}
}
}
public class Query
{
public void Select(string query)
{
DBConnect QConnect = new DBConnect();
// Here I want to call this class somewhere and pass
// query string to it and return result from select stmt
MySqlCommand command = new MySqlCommand(QConnect.Initialize(),query);
// here I get error Unable to convert void to string...
}
}
}
I am searching and reading from 2 days now, and there is nowhere solution to this problem, I am wondering what to do.Would be really really thankful if somebody of you guys give me books or something to read,and learn c# from.
First of, the MySqlCommand constructor takes a MySqlConnection and a string query as arguments but your DBConnect.Initialize method is void.
The second issue is that the connection is disposed as soon as it leaves the using statement in the Initialize method which means you can't reuse it (if that is what you trying to do..)
using (connection = new MySqlConnection(connectionString))
{
connection.Open();
}
What you can do instead is to return the connection from initialize and wrap your db operation in a using statement in the calling method
Update the DBConnect Initialize method to return the MySqlConnection instance
public static MySqlConnection Initialize()
{
server = "testing.com";
database = "mus_le";
uid = "muff";
password = "test";
string connectionString = "Server=" + server + ";"+"Database=" + database + ";" + "Uid=" + uid + ";" + "Password=" + password + ";";
return new MySqlConnection(connectionString);
}
Then use it
public void Select(string query)
{
using (var connection = DBConnect.Initialize())
using (var command = new MySqlCommand(connection,query))
{
}
}
Your method Initialize returns void, it should return the connection instead :
public static MySqlConnection Initialize()
{
server = "testing.com";
database = "mus_le";
uid = "muff";
password = "test";
string connectionString = "Server=" + server + ";"+"Database=" + database + ";" + "Uid=" + uid + ";" + "Password=" + password + ";";
return new MySqlConnection(connectionString))
}
and then you would use it like this :
public class Query
{
public void Select(string query)
{
DBConnect QConnect = new DBConnect();
// Here I want to call this class somewhere and pass
// query string to it and return result from select stmt
using (MySqlConnection conn = QConnect.Initialize())
{
conn.Open();
MySqlCommand command = new MySqlCommand(conn,query);
}
}
}
But as the comments say, these objects are usually provided...
If you want to reuse your class you can simply create is a base class for any others. Every newly created class can inherit from the base and have an access to database without reusing the code. There is a base method for Select(). You can add also any other SQL operation there.
public class DbContext
{
private static MySqlConnection connection;
private static string server;
private static string database;
private static string uid;
private static string password;
private static string ConnectionString = "Server=" + server + ";" + "Database=" + database + ";" + "Uid=" + uid + ";" + "Password=" + password + ";";
static DbContext()
{
server = "testing.com";
database = "mus_le";
uid = "muff";
password = "test";
}
protected object Select(string query)
{
using (connection = new MySqlConnection(connectionString))
{
connection.Open();
DBConnect QConnect = new DBConnect();
// Here I want to call this class somewhere and pass
// query string to it and return result from select stmt
MySqlCommand command = new MySqlCommand(QConnect.Initialize(), query);
// here I get error Unable to convert void to string...
//return result
return null;
}
}
}
public class SomeNewReader : DbContext
{
public object SelectSomething()
{
return base.Select("some query");
}
}
public class SomeNewReader1 : DbContext
{
public object SelectSomething()
{
return base.Select("some query");
}
}
To answer your question for books and something to read.
You should always look at learn.microsoft.com, often there are good examples that explain how these classes are used, additionally search for keywords on google or codeproject.com like listed below in combination with C# oder .NET
Data access layer (DAL)
Data access object (DAO)
Further, you can improve your skills with reading something about OOP design patterns Elements of Reusable Object-Oriented Software - Erich Gamma et al.
e.g. Factory Pattern - should be used to create a specific database from an abstraction
In the modern OOP frameworks today, you will find implementations with using dependency injection to decouple infrastructure code (e.g. your database and sql-statements) from business logic (e.g. specific operations on data).
For the csharp-language itself they are literally available as the sand of the sea. It depends on your OOP and programming skills which one fits for you. Professional C# 7 and .NET Core
Im making a project in C# ASP.NET with MySQL. Im trying to open a MySql connection correctly. Also close/dispose this connection correctly. Becouse it gives That error sometimes
"mySQL ERROR: system lacked sufficient buffer space or because a queue
was full."
Anyway so I decided to use "using" method my current connection method like that;
MySqlConnection baglanti = new MySqlConnection(ConfigurationManager.ConnectionStrings["mysqlbaglanti"].ToString());
void GirisYap()
{
using (var cn = baglanti)
{
cn.Open();
using (MySqlCommand cmd = new MySqlCommand("SELECT * FROM kullanicilar WHERE kullaniciadi='" + txtKullaniciAdi.Text + "' AND sifre='" + txtSifre.Text + "'"))
{
using (MySqlDataReader oku = cmd.ExecuteReader())
{
if (oku.Read())
{
Session.Add("AdSoyad", oku["AdSoyad"]);
Session.Add("sesid", oku["kullaniciid"]);
Response.Redirect("AnaSayfa.aspx");
}
else
{
lblDurum.Text = "Yanlış Kullanıcı Adı/Şifre !";
}
}
}
}
}
but its gives an error that "Connection must be valid and open." what am I doing wrong?
in using you should create new IDisposible object. When you exit using scope, it will be disposed.
In your code, you generate connection during class object construction. After first usage of cn, your baglanti object will be disposed. After first usage, you cannot open connection. Hence, you should generate connection object in using statement.
All above is advice, not solution of your problem. Your problem is that, command object does not have connection object. You can pass connectin object to command object via constructor
You should use like:
string connectionStr = ConfigurationManager.ConnectionStrings["mysqlbaglanti"].ToString());
void GirisYap()
{
using (var cn = new new MySqlConnection(connectionStr))
{
cn.Open();
// command object should take connection object
using (MySqlCommand cmd = new MySqlCommand("SELECT * FROM kullanicilar WHERE kullaniciadi='" + txtKullaniciAdi.Text + "' AND sifre='" + txtSifre.Text + "'", cn))
{
........
}
}
I got this error :
"There is already an open DataReader associated with this Command which must be closed first"
private readonly object _syncRoot = new object();
public void SqlConnect(string server, string db, string user, string pw)
{
lock (_syncRoot)
{
new_conn = new SqlConnection("Server=" + server + ";Database=" + db + ";User Id=" + user + ";Password=" + pw + ";");
new_conn.Open();
}
}
public string ReadString(string query)
{
string strResult = null;
using (SqlCommand command = new SqlCommand(query, new_conn))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
strResult = Convert.ToString(reader[0]);
}
reader.Close();
}
}
return strResult;
}
I can't find what is wrong with that code?
Before calling SqlCommand you must check if your connection is still alive using the new_com.Status properties.
Personally i use a property to get the connection and in the get of this property i create the connection if it doesn't exist and if the status is not open i open it.
I have been doing applications on Java, connected with MySQL, but now I am doing C# with Oracle.
Here is the code I've got so far:
using System.Data.OracleClient;
namespace Chat
{
class DBconnector
{
static private string GetConnectionString()
{
return "Data Source=myserver.server.com;Persist Security Info=True;" +
"User ID=myUserID;Password=myPassword;Unicode=True";
}
static public void ConnectAndQuery()
{
string connectionString = GetConnectionString();
using(OracleConnection conn = new OracleConnection())
{
conn.ConnectionString = connectionString;
conn.Open();
Console.WriteLine("State: " + conn.State);
Console.WriteLine("Connction String: " + conn.ConnectionString);
OracleCommand command = conn.CreateCommand();
string sql = "SELECT * FROM users";
command.CommandText = sql;
OracleDataReader reader = command.ExecuteReader();
while(reader.Read())
{
string myField = (string)reader["MYFIELD"];
Console.WriteLine(myField);
}
}
}
}
}
What is hacking me is that I don't know what to type in exchange of "myserver.server.com", "myUserID" and the "myPassword" in the connectionString.
I suppose it's "localhost/" and smth like that, but with Oracle I don't really have the same visual interface as with MySQL in the browser and thus I am kinda' lost.
I followed this tutorial: Instant Oracle using C#
and I am doing the case with including the connection String directly in my code, but not using the tsanames.ora external file.
Long story short -> I am not sure how to modify the connection string for my own database and if there are any other mistakes or suggestions - feel free to state them.
I'm not sure if you can do this without modifying your tnsnames, but it's not hard:
YOURSERVER = (DESCRIPTION = (ADDRESS = (PROTOCOL= TCP)
(Host= <your_server_hostname_or_IP>)(Port= <port>))(CONNECT_DATA = (SID = <DB_instance name>)) )
If you have doubts on how to fill these up, you should check with your nearest DBA.
Then just add YOURSERVER in:
return "Data Source=YOURSERVER; ...
Username and password are those related to the schema you want to connect.