I am new to C# and I started studying just yesterday.
I have created class to connect to SQL Server:
namespace Exchange_Ofiice.Classes
{
public class sqlConn
{
public void connectionMethod()
{
SqlConnection myConnection = new SqlConnection("user id=ID;password=PASS;server=SERVER;database=DB;");
try
{
myConnection.Open();
}
catch
{
MessageBox.Show("Невозможно подключиться к Базе данных. Пожалуйста обратитесь к программистам!", "Ошибка подключения к Базе данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
myConnection.Close();
}
}
}
}
and another class for user authentification:
namespace Exchange_Ofiice.Classes
{
public class auth:sqlConn
{
public void authMethod()
{
SqlCommand myCommand = new SqlCommand("Command String", myConnection);
}
}
}
How to get (use) SQL connection result (myConnection) in second class?
P.S. line SqlCommand myCommand = new SqlCommand("Command String", myConnection); does not work.
P.S.S. Sorry, if I have mistake, my english is not perfect.
Try this. So you have the SQLConnection in the class and not in the function.
If you declare something in a function it will only be accessible in that function.
public class sqlConn
{
public SqlConnection myConnection;
public void connectionMethod()
{
myConnection = new SqlConnection("user id=ID;password=PASS;server=SERVER;database=DB;");
try
{
myConnection.Open();
}
catch
{
MessageBox.Show("Невозможно подключиться к Базе данных. Пожалуйста обратитесь к программистам!", "Ошибка подключения к Базе данных", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
myConnection.Close();
}
}
}
Oh you might want to consider making the SQLConnection private
private SqlConnection myConnection;
And then make a function to retrieve the value.
public SqlConnection GetConnection()
{
return myConnection;
}
And in the other class it will be:
SqlCommand myCommand = new SqlCommand("Command String", GetConnection());
First of all, connection should be public field of your class, not function variable. And secondly, you're closing your connection in finally, so you have no chance to make it working later.
public class sqlConn
{
public SqlConnection myConnection = new SqlConnection("user id=ID;password=PASS;server=SERVER;database=DB;");
public void connectionMethod()
{
try
{
myConnection.Open();
}
catch
{
//Here goes error handling...
}
}
}
And, surely, in your authMethod you should make checks for connection state, to prevent exceptions, if connection was not initialized.
Also, as good practice, make sure you're implementing IDisposable interface (http://msdn.microsoft.com/en-us/library/system.idisposable.aspx) for your connection class, otherwise you might have some troubles later.
Related
This did not worked when I ran the program!
using MySql.Data;
using MySql.Data.MySqlClient;
namespace MySQL
{
class SqlConnection
{
public SqlConnection() { }
~SqlConnection() { }
private string strConnection = "Server=localhost;Database=database;Port=3306;User ID=root;Password=";
private MySqlConnection connection;
public void OpenConnection()
{
connection = new MySqlConnection();
connection.Open();
}
public void CloseConnection()
{
connection.Close();
connection.Dispose();
}
public string StrConnection
{
set
{
StrConnection = value;
}
get
{
return StrConnection;
}
}
}
}
but it is not working!
ERROR : host 'xxx' is not allowed to connect to this MariaDB sever!
You don't use the connection string property strConnection, when you initialize your connection. Try:
public void OpenConnection()
{
connection = new MySqlConnection(strConnection);
connection.Open();
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Just 1st student rotating from java to C# here. When we were studying Java we were given this kind of SQL connection manager class thing, which is just basically just bunch of code to make it easier accessing it in different classes (It's written by my danish teacher and has some misspells/inside jokes, not sure):
public class DbConnection
{ //Constants used to get access to the database
//SQL Server
private static final String driver = "nope";
// private static final String driver = "nope";
private static final String databaseName = ";databaseName=nope";
//SQL Server
// private static String userName = ";user=sa";
private static String userName = "; user=nope";
private static String password = ";password=nope";
private DatabaseMetaData dma;
private static Connection con;
// an instance of the class is generetated
private static DbConnection instance = null;
// the constructor is private to ensure that only one object of this class is created
DbConnection()
{
String url = driver + databaseName + userName + password;
try{
//load af driver
//SQL Server
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
System.out.println("Load af class ok");
}
catch(Exception e){
System.out.println("Can not find the driver");
System.out.println(e.getMessage());
}//end catch
try{
//connection to the database
con = DriverManager.getConnection(url);
//set autocommit
con.setAutoCommit(true);
dma = con.getMetaData(); // get meta data
System.out.println("Connection to " + dma.getURL());
System.out.println("Driver " + dma.getDriverName());
System.out.println("Database product name " + dma.getDatabaseProductName());
}//end try
catch(Exception e){
System.out.println("Problems with the connection to the database");
System.out.println(e.getMessage());
System.out.println(url);
}//end catch
}//end constructor
//closeDb: closes the connection to the database
public static void closeConnection()
{
try{
con.close();
System.out.println("The connection is closed");
}
catch (Exception e){
System.out.println("Error trying to close the database " + e.getMessage());
}
}//end closeDB
//getDBcon: Get-method, returns the connection to the database
public Connection getDBcon()
{
return con;
}
//this method is used to get the instance of the connection
public static DbConnection getInstance()
{
if (instance == null)
{
instance = new DbConnection();
}
return instance;
}
public static void startTransaction()
{ try{
con.setAutoCommit(false);
}
catch(Exception e){
System.out.println("fejl start transaction");
System.out.println(e.getMessage());
}
}
public static void commitTransaction()
{ try{
con.setAutoCommit(true);
}
catch(Exception e){
System.out.println("fejl commit transaction");
System.out.println(e.getMessage());
}
}
public static void rollbackTransaction()
{ try{
con.rollback();
con.setAutoCommit(true);
}
catch(Exception e){
System.out.println("fejl rollback transaction");
System.out.println(e.getMessage());
}
}
}//end DbConnection
So to get used to C# for second year i thought of first of recreating this in C# and first of all: Is it good idea to have it in C#? I see many people just using
using(SqlConnection....){}
thing and I'm not sure how to implement autoCommits/Transaction rollbacks since for example transactions in C# are different classes
So far i made this little class:
class DbConnection
{
private const string DB_USER_ID = "user id=sa;";
private const string DB_USER_PASSWORD = "password=nope;";
private const string DB_SERVER_URL = #"server=localhost\SQLExpress1;";
private const string DB_NAME = "database=test; ";
private const string DB_TIME_OUT = "connection timeout=30";
private const string DB_TRUSTED_CONN = "Trusted_Connection=yes;";
private static SqlConnection myConnection = null;
private static DbConnection instance = null;
// private constructor to ensure that only object of this class is created
private DbConnection()
{
createConnection();
}
// Instantiates SqlConnection object
private void createConnection()
{
Console.WriteLine("Attempting to create connectiong...");
try
{
myConnection = new SqlConnection(DB_USER_ID +
DB_USER_PASSWORD +
DB_SERVER_URL +
DB_TRUSTED_CONN +
DB_NAME +
DB_TIME_OUT);
}
catch (Exception e)
{
Console.WriteLine("Problems with the connection to the database");
Console.WriteLine(e.Message);
}
}
private void openConnection()
{
try{
myConnection.Open();
Console.WriteLine("Connection succesfful!");
} catch(Exception e) {
Console.WriteLine(e.StackTrace);
}
}
public static void closeConnection()
{
try
{
myConnection.Close();
Console.WriteLine("Connection closed");
}
catch (Exception e)
{
Console.WriteLine("Problem closing connection");
Console.WriteLine(e.Message);
}
}
public SqlConnection getDBcon()
{
return myConnection;
}
public static DbConnection getInstance()
{
if (instance == null)
{
instance = new DbConnection();
}
return instance;
}
}
Man, that DbConnection class is bad stuff. Throw it away. In VB the author would have used ON ERROR RESUME NEXT.
The main problem is that errors are just thrown away. The program continues in a bad state.
Next problem is a static (globally shared) connection object. That's not thread-safe and if the connection ever breaks (network issue) it permanently breaks.
.NET has connection pooling. This class is something you don't need. Maybe you can write yourself a little helper to open a connection:
static SqlConnection CreateConnection() {
...
}
using (var conn = CreateConnection()) {
}
How much more simple can it be?
Of course there are many answers for this question,though,I got no clear Idea for my problem.
I'm working on Visual Studio.I have 2 forms as one is weeklyGVadminview and dailyGVadminview..
I wrote a function(method) in dailyGVadminview which is needed now in another form.....
I'm adding my code here..Any ansers will be appreciated in advance thanks.
namespace weeklyattendance
{
public partial class dailyGvAdminview : Form
{
public dailyGvAdminview()
{
InitializeComponent();
}
private void datechanges()
{
string date = dateTimePicker1.Value.ToString("dd/MM/yyyy");
var connectionstring = ConfigurationManager.ConnectionStrings["attendancemanagement"].ConnectionString;
SqlConnection cn = new SqlConnection(connectionstring);
string query = "select count(Employee_id) from employee_details";
cn.Open();
SqlCommand cmd = new SqlCommand(query, cn);
object result =cmd.ExecuteScalar();
txttotalstaff.Text = (result.ToString());
cn.Close();
}
}
}
Form2 code as follows
namespace weeklyattendance
{
public partial class weeklyGvAdminView : Form
{
public weeklyGvAdminView()
{
InitializeComponent();
}
}
private void dateTimePicker1_ValueChanged_1(object sender, EventArgs e)
{
//here I want to call that function or method
}
}
So I would just create a new class and put the method on that class:
public class DbHandler
{
public string DateChanges()
{
string date = dateTimePicker1.Value.ToString("dd/MM/yyyy");
var connectionstring = ConfigurationManager.ConnectionStrings["attendancemanagement"].ConnectionString;
SqlConnection conn = new SqlConnection(connectionstring);
string query = "select count(Employee_id) from employee_details";
conn.Open();
SqlCommand cmd = new SqlCommand(query, conn);
object result = cmd.ExecuteScalar();
var result = result.ToString();
conn.Close();
return result;
}
}
Then in your classes do this:
var dbHandler = new DbHandler();
var result = dbHandler.DateChanges();
I would try and follow some conventions as well. Makes it easier for other programmers to follow what is going on.
You can create object of dailyGvAdminview and call for that try below code :-
namespace weeklyattendance
{
public partial class weeklyGvAdminView : Form
{
public weeklyGvAdminView()
{
InitializeComponent();
}
}
private void dateTimePicker1_ValueChanged_1(object sender, EventArgs e)
{
var form1 = new dailyGvAdminview();
//// call function using this instance
}
}
If you want to access method from outside then make it to Public as shown below :-
public string DateChanges()
{
}
If you want a really GLOBAL and easy solution do this, first you make a static class.
namespace weeklyattendance
{
public static class Obj
{
public static dailyGvAdminview globalDaily;
}
}
Then in your initialize or onLoad code where you create this class just write
Obj.globalDaily = this;
Now you can access this class anywhere in your program with Obj.globalDaily, you can also add whatever else you want in there and access it like that
I'm trying to build a class that will be responsible for all operations on database.
Using singleton pattern from here: http://codebender.denniland.com/a-singleton-base-class-to-implement-the-singleton-pattern-in-c/
I've build a class like so:
class DB : SingletonBase<DB>
{
public static readonly string SqlConnectionString = #"Data Source=MYDB;Initial Catalog=PRODUCTS;Integrated Security=True;Asynchronous Processing=true;";
private DB()
{
}
public void loadData()
{
SqlConnection conn = new SqlConnection(SqlConnectionString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "STATISTICS_1";
cmd.Connection = conn;
conn.Open();
IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback(HandleCallback), cmd, CommandBehavior.CloseConnection);
}
private void HandleCallback(IAsyncResult result)
{
SqlDataReader dr;
SqlCommand _this = (SqlCommand)result.AsyncState;
if (result.IsCompleted)
{
dr = _this.EndExecuteReader(result);
}
else
dr = null;
DataTable dt = new DataTable();
dt.Load(dr);
dr.Close();
MessageBox.Show("loaded");
}
}
In my main class I'm using this like so:
private void loadStatistics(object sender, EventArgs e)
{
showStatus("loading data");
DB.Instance.loadData();
}
But this will give me only my message box.
What I would like to do is to declare function in my main class that will be called after SQL query return something.
I think that the best way would by using events, but I don't know how to do that proper way.
I would like to do something like this in my main class:
private void loadCompleted(string msg)
{
MessageBox.Show(msg);
}
private void loadStatistics(object sender, EventArgs e)
{
showStatus("loading data");
DB.Instance.loadData(loadCompleted);
}
So that I can specify function that will be called after SQL call is finished.
I don't know if this is the best way of doing this, so any comments, suggestions and solutions are welcome.
What I would like to achieve is to have one class responsible for calling SQL asynchronously and passing data to other functions that will process it.
public delegate void NotifyCallback(string message);
public class ClassWithCommandAndCallback
{
public SqlCommand Sql;
public NotifyCallback Callback;
}
public void loadData(NotifyCallback callback)
{
ClassWithCommandAndCallback ar = new ClassWithCommandAndCallback();
ar.Sql = cmd;
ar.Callback = callback;
IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback(HandleCallback), ar, CommandBehavior.CloseConnection);
}
private void HandleCallback(IAsyncResult result)
{
ClassWithCommandAndCallback ar = (ClassWithCommandAndCallback)result.AsyncState;
ar.Callback("loaded (SQL was: "+ar.Sql+")");
}
I have a class that is responsible for all my Database actions, in general it calls stored procedures.
I've created 2 delegates in my class, one responsible for positive response (server returned OK for example) and second for all error handling.
public delegate void Part1_Callback(string message);
public delegate void Part2_Callback(DataTable dt);
public delegate void Part3_Callback(DataTable dt, int x, int y);
public delegate void ErrorHandler(string message);
I call all methods asynch like shown in my previous question: C# asynch SQL inside singleton and delegates
I have a problem when I need my delegate to return a different type of data.
For example my first method returns a String, second a DataTable, and third a DataTable and 2 ints.
Right now for every method I must create class that holds parameters:
public class Part1_CommandAndCallback
{
public SqlCommand Sql;
public Part1_Callback Callback;
public ErrorHandler Error;
}
public class Part2_CommandAndCallback
{
public SqlCommand Sql;
public Part2_Callback Callback;
public ErrorHandler Error;
}
public class Part3_CommandAndCallback
{
public SqlCommand Sql;
public Part3_Callback Callback;
public ErrorHandler Error;
}
Is it possible to create one generic delegate so that I will be able to have one delegate for responses and one class for parameters?
This way I'll be able to more easily control my code.
I found article on codeproject: http://www.codeproject.com/Articles/192027/Delegates-101-Part-III-Generic-Delegates but I don't know how to use this in my case :/
Should I declare my delegate like this:
delegate void MyDelegate (params object[] params);
or:
public delegate void MyDelegate2<T>(T param1);
but this way I'll be able to pass only one parameter, I won't be able to use same delegate for 3 parameters.
Which solution is better?
I would like to have one generic delegate that will be able to take one-to-three parameters with different types.
Can this be done?
EDIT:
I'll try to show my scenario:
In my main form class I'm calling my DB class like so:
private void form1_Enter(object sender, EventArgs e)
{
showStatus("Loading statistics...");
DB.Instance.Part1(part1_ok,ErrorHandler);
DB.Instance.Part2(part2_ok, ErrorHandler);
}
private void ErrorHandler(string msg)
{
hideStatus();
//viewStack1.InvokeIfRequired(c => { c.moveToFirst(); });
MessageBox.Show(msg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private void part1_ok(string msg)
{
MessageBox.Show(msg);
}
private void part2_ok(DataTable dt)
{
dataGridView1.InvokeIfRequired(c =>
{
c.DataSource = dt;
});
}
My DB class looks like so:
public delegate void Part1_Callback(string message);
public delegate void Part2_Callback(DataTable dt);
public delegate void Part3_Callback(DataTable dt, int x, int y);
public delegate void ErrorHandler(string message);
public class Part1_CommandAndCallback
{
public SqlCommand Sql;
public Part1_Callback Callback;
public ErrorHandler Error;
}
public class Part2_CommandAndCallback
{
public SqlCommand Sql;
public Part2_Callback Callback;
public ErrorHandler Error;
}
public class Part3_CommandAndCallback
{
public SqlCommand Sql;
public Part3_Callback Callback;
public ErrorHandler Error;
}
class DB : SingletonBase<DB>
{
public static readonly string SqlConnectionString = #"Data Source=MyDB;Initial Catalog=Stats;Integrated Security=True;Asynchronous Processing=true;";
private DB()
{
}
public void Part1(Part1_Callback callback, ErrorHandler error)
{
SqlConnection conn = new SqlConnection(SqlConnectionString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Part1";
try
{
conn.Open();
}
catch (Exception ex)
{
error(ex.ToString());
return;
}
Part1_CommandAndCallback ar = new Part1_CommandAndCallback() { Callback = callback, Error = error, Sql = cmd };
IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback(Part1_Handler), ar, CommandBehavior.CloseConnection);
}
private void Part1_Handler(IAsyncResult result)
{
string stats = string.Empty;
Part1_CommandAndCallback ar = (Part1_CommandAndCallback)result.AsyncState;
SqlDataReader dr;
if (result.IsCompleted)
{
dr = ar.Sql.EndExecuteReader(result);
}
else
dr = null;
while (dr.Read())
{
stats += dr[0].ToString() + Environment.NewLine;
}
dr.NextResult();
while (dr.Read())//problem is here
{
stats += dr[0].ToString() + " - " + dr[1].ToString() +Environment.NewLine;
}
dr.Close();
ar.Callback(stats);
}
public void Part2(Part2_Callback callback, ErrorHandler error)
{
SqlConnection conn = new SqlConnection(SqlConnectionString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Part2";
try
{
conn.Open();
}
catch (Exception ex)
{
error(ex.ToString());
return;
}
Part2_CommandAndCallback ar = new Part2_CommandAndCallback() { Callback = callback, Error = error, Sql = cmd };
IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback(Part2_Handler), ar, CommandBehavior.CloseConnection);
}
private void Part2_Handler(IAsyncResult result)
{
DataTable dt = new DataTable();
Part2_CommandAndCallback ar = (Part2_CommandAndCallback)result.AsyncState;
SqlDataReader dr;
if (result.IsCompleted)
{
dr = ar.Sql.EndExecuteReader(result);
}
else
dr = null;
dt.Load(dr);
dr.Close();
ar.Callback(dt);
}
}
My idea was to use my singleton DB controller in many forms at the same time. So in first form I'll see some stats that will auto refresh, and if I'll like then is second form I'll be able to see some different stats that I'll be able to refresh on button click.
I would use the built in delegates I think,
Action<T>
Action<T, T>
etc
See here:
http://msdn.microsoft.com/en-us/library/018hxwa8.aspx
It looks like what you need is to create a generic CommandAndCallback class:
public class CommandAndCallback<TCallback>
{
public SqlCommand Sql;
public TCallback Callback;
public ErrorHandler Error;
}
And, for example, where you previously used Part3_CommandAndCallback, you would now use CommandAndCallback<Part3_Callback> or even CommandAndCallback<Action<DataTable, int, int>>, if you didn't want to create a delegate type for each part either.
Also, public fields are generally discouraged, so you might consider changing them to autoproperties:
public class CommandAndCallback<TCallback>
{
public SqlCommand Sql { get; set; }
public TCallback Callback { get; set; }
public ErrorHandler Error { get; set; }
}