I would like to apply my connection string to the whole winform. If I do this in this case - it will apply to the whole win form, but then i cannot use textbox to enter details:
public partial class Form1 : Form
{
SqlConnection myConnection = new SqlConnection("user id=userName;" +
"password=userPass;" +
"server=.;" +
"Trusted_Connection=yes;" +
"database=dbName; " +
"MultipleActiveResultSets=True;" +
"connection timeout=30");
public Form1()
{
InitializeComponent();
}
And if I will use with textbox I will need to enter the connection string to each method.
Is there anyway to get around it?
Another approach you can take is create the SqlConnection when it is needed and then store in a private variable if you want to save the reference.
So when you need the connection have:
if( myConnection == null )
{
string connectionString = string.Format( "user id={0}, password={1}", userIdTextBox.Text, passwordTextBox.Text );
myConnection = new SqlConnection( connectionString );
}
You will extend the "string.Format" to include the other connection properties.
If you require the "myConnection" in multiple places then place the above code into a method named "GetConnection", have it return an SqlConnection instance using the contents of the textboxes and call this method each time a connection is required.
EDIT:
Personally I would have a method that builds the connection string, like described above, and create a new SqlConnection instance whenever it is needed. This will attempt to open a new connection each time, but will make use of connection pooling built into the ADO.NET library.
using( SqlConnection connection = new SqlConnection( this.GetConnectionString() ) )
{
// Open Connection
// Access the database
// Close the connection <- Manual closing MAY not be needed as it might be done in Dispose ...check MSDN for clarification.
}
You can create a static class to store the connection string in there. It is not a good practice to create always the connection string.
Related
I'm new to C#. This is, in fact my first project in this particular language.
In the following code:
namespace FuelBurnImport {
class DataWriter {
private string qs = "SELECT * FROM fuel_burn_data_meta;";
public DataWriter(BurnDataHeader bdh, BurnDataFlight bdf) {
SqlConnection cn = OpenCN();
// work in progress. more to be added here...
}
private SqlConnection OpenCN() {
private string cs = #"Data Source=server; APP=FuelBurnImporter; Initial Catalog=database; Integrated Security=true";
return new SqlConnection(cs).Open();
}
}
}
I get intellisense errors in the OpenCN() private method
the OpenCN() method declaration says Not all code paths return a
value
the { following the OpenCN() { method declaration says expected
"}"
the end of line private string cs also says expected "}"
the cs in new SqlConnection(cs) says does not exist in current
context
new SqlConnection(cs).Open() error says "a namespace cannot directly contain members..."
However, if I remove private from in front of private string cs, all these errors go away and it appears to be happy.
Am I misusing the private method in some way? Am I misusing the private string declaration? I have a feeling that even if I remove the private from in front of the string field declaration, it's still going to break.
The string declaration within a method is local, so it makes no sense to make it private. Thus, you are committing a syntax error (and, in my view, a semantic error) by using the private keyword in there. The variable cn cannot possibly leak as it's inaccessible from other methods, and different instances of the same method on the same object have different "cs" things (I'm not sure but you can create a private static const string outside the method and use it in the method, if you really want to see "private" in the declaration of the variable).
Fix this first.
Before the actual return occurs, the "using" statement will automatically close the connection and you'd return a closed connection. This may or may not cause a syntax error, but if it does, I'd say it should be more explicit.
Make cn a private member of the class;
Do not use using {} or dispose cn in an other way in OpenCN;
Implement IDisposable on your class.
https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx
Don't put using in OpenCN. using ensures that the variable created is disposed. If you do that you'll be returning a SqlConnection which has already been closed.
Instead, change OpenCN to this:
private SqlConnection OpenCN()
{
var cs = #"Data Source=server; APP=FuelBurnImporter; Initial Catalog=database; Integrated Security=true";
var cn = new SqlConnection(cs);
cn.Open();
return cn;
}
Also, don't call OpenCN from the constructor. That's going to create an opened connection when you create an instance of DataWriter. Don't create and open a connection until you need it. That way you can create it, open it, use it, and then dispose it (which also closes it) as soon as possible.
Whatever the method is that's going to actually execute some SQL, create the connection there. If you call OpenCN from there, then you would do
using(var connection - OpenCN())
{
//execute your SQL using the connection
}
Regarding your error, just remove the private keyword from the connection string declaration:
private string cs = #"Data Source=server; APP=FuelBurnImporter; Initial Catalog=database; Integrated Security=true";
However, you will have some problems because your connection will be closed as soon as using stament completes. Also it's not recommended to open your connections for long time. Simply make the using statement and open the connection just at the moment when you need to execute the query.
After using block "}" - return null because using block only return the value not the function
No need declare private string inside function
Better way function implementation
private SqlConnection OpenCN()
{
string cs = #"Data Source=server; APP=FuelBurnImporter; Initial Catalog=database; Integrated Security=true"; SqlConnection cn = new SqlConnection(cs);
cn.Open();
return cn;
}
I'm a beginner.
I already found a way to connect to SQL SERVER using the codes below:
private void getListBtn_Click(object sender, RoutedEventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=myDB;Integrated Security=true;");
SqlDataAdapter sda = new SqlDataAdapter("SELECT ID,Date,Name,City FROM Info;", con);
DataTable dt = new DataTable();
sda.Fill(dt);
dataGridForm.ItemsSource = dt.DefaultView;
I also wanted to get number of rows from a TABLE and set it to a label, But it's not a good idea to copy and paste this code again, I want to have a method for sqlconnection so i won't rewrite this code again and again for every single query.
Sorry i'm an absolute beginner, 3 days since i started learning C# WPF.
Yes some frameworks and/or ADO's solutions are good and maybe the best "professionnal" approch, you say you're a beginner and I was it not so far ;-).
So the simpliest way is to add a new class for the sql connection. In example add a Sqlconnect.cs class.
using System.Data.SqlClient;
public class Sqlconnect
{
public SqlConnection Con { get; set; }//the object
private string conString { get; set; }//the string to store your connection parameters
}
This class will have a method to open the connection and one to close it.
public void conOpen()
{
conString = "Data Source=..."; //the same as you post in your post
Con = new SqlConnection(conString);//
try
{
Con.Open();//try to open the connection
}
catch (Exception ex)
{
//you do stuff if the connection can't open, returning a massagebox with the error, write the error in a log.txt file...
}
}
public void conClose()
{
Con.Close();//close the connection
}
In your other(s) classe(s) where you need a sql query you first instantiate an new object.
private void getListBtn_Click(object sender, RoutedEventArg e)
{
Sqlconnect con = new Sqlconnect();//instantiate a new object 'Con' from the class Sqlconnect.cs
con.conOpen();//method to open the connection.
//you should test if the connection is open or not
if(con!= null && con.State == ConnectionState.Open)//youtest if the object exist and if his state is open
{
//make your query
SqlDataAdapter sda = new SqlDataAdapter("your query", con);
//etc
con.conClose();//close your connection
}
else
{
//the connection failed so do some stuff, messagebox...as you want
return;//close the event
}
}
this example need some ameliorations, it's evident but I wrote it like this to be clearest.
First thing this is not related to WPF, this is general coding even I would not consider this to be related to .net.
For your current problem to show the count, you dont have to make a call again. You can get the count from the datatable row count. But, I would suggest few things:
You should have one or different separate layers like business, data access etc. as per your needs.
You should not give the connection as the way you have provided here.
You can choose to use any ORMs like entity framework, NHibernate etc based on your needs. This just a direction, you can choose to stick with ADO.Net as you have it your choice. But I would definitely suggest to throw in more layers to avoid duplicate codes and more structured approach.
Best choice if you don't need so much performance is ORM like Entity Framework.
Here is something of basics.
Just use it like in MVC app.
If we copy paste your code, then the error is appearing. I have corrected it and maybe others don't need to struggle like me to find this. :)
// Object exists and State is open
if (Conex != null && Conex.Con.State ==
System.Data.ConnectionState.Open)
{
// Create a String to hold the query
string query = "insert into Xray_Table values
(25,'zzz','hij',3,'uuu',6,'2012-06-18
10:34:09.000')";
// Create a SqlCommand object and pass the constructor the connection string and the query string
SqlCommand queryCommand = new SqlCommand(query, Conex.Con);
// Execute the query to update to the database
queryCommand.ExecuteNonQuery();
// method to close the connection.
Conex.conClose();
}
There is no error in this code but when i insert the values,they are not actually inserted in database.
Here is my connection string class :
public class DBConn
{
public static SqlConnection GetConnection()
{
string sDBPath = Application.StartupPath + #"\App_Data\Database3.mdf";
string connStr = #"Data Source=.\SQLEXPRESS;AttachDbFilename='" + sDBPath + "';Integrated Security=True;User Instance=True";
return new SqlConnection(connStr);
}
}
and in this class i call the connection string class :
string query = "INSERT INTO Table1 VALUES('" + textBox1.Text + "')";
SqlConnection con = DBConn.GetConnection();
SqlCommand com = new SqlCommand(query,con);
con.Open();
using (con)
{
com.ExecuteNonQuery();
MessageBox.Show("Insert");
}
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// Do work here; connection closed on following line.
}
Your use of the using statement is not recommended and leads to
problems. You have to instantiate the resource object inside the
using statement! It's scope or lifetime is now limited to the
statement block and will be properly garbage collected. The way you
use it (by passing an already instantiated object into the using
statement) the objects remains valid although not properly accessible
since it was never properly closed or disposed. MSDN - using
statement. So instead of creating the connection and passing it
around your application (bad practice) you should create the
connection settings (connection string) and the query and use
them to create a connection resource inside a using statement
everytime you need a connection. This way the resource is
always correctly disposed. The provided link gives you an
example how to use a using statement.
Check your connection string well if all provided information is
valid or all needed information is provided (e.g. username and password).
Check database settings (e.g. permissions)
SqlConnection class has an event called InfoMessage. In case the
connection produces any warnings or errors you will get notified.
Check your database (e.g. log) for the occurance of errors.
i am developing window application and i want the user of the app can change the connection string so i create aform to save connection string to setting and able to retrieve it but the problem is how to use this setting
private void button1_Click(object sender, EventArgs e)
{
var serv = Properties.Settings.Default.server;
var db = Properties.Settings.Default.database;
var userid = Properties.Settings.Default.userid;
var pass = Properties.Settings.Default.password;
SqlConnection conn = new SqlConnection("Data Source=serv;Initial Catalog=db;User ID=userid password=pass");
SqlDataAdapter sda = new SqlDataAdapter("SELECT count(*) FROM users WHERE username='" + txtUsername.Text + "' and password='" + txtPassword.Text + "'", conn);
}
Put your connection string in the App.config/Web.config, it will make it that much easier to alter later on if need be.
Also remember to always make use of the using statement when working with SqlConnection in general.
For example:
In the App.config/Web.config add the following:
<appSettings>
<add key="myConnectionString" value="Data Source=serv;Initial Catalog=db;User ID=userid password=pass" />
</appSettings>
Then you can easily access it anywhere in your project:
using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["myConnectionString"]))
{
using(SqlCommand sqlCommandConn = new SqlCommand(InsertStatement))
{
sqlCommandConn.Connection = conn;
//TODO: Open connection, Execute queries...
}
}
Note
You can alter these settings via code as well if you wish:
private void UpdateConfig(string key, string value)
{
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
configFile.AppSettings.Settings[key].Value = value;
configFile.Save();
}
Try
SqlConnection conn = new SqlConnection("Data Source=" + serv.ToString() + ";Initial Catalog=" + db.ToString() + ";User ID=" + userid.ToString() + ";password= " + pass.ToString());
As you can see from your code snippet, the connection string value is just a string that you are passing to the SqlConnection constructor, so for your case you could pull the value at runtime and load that value dynamically.
While it is possible to manipulate the app.config file which does hold connection string values, I typically prefer to manipulate secondary files. A better option could be to use a secondary file in XML for example and preform CRUD like operations on it as your users change their connection strings. At runtime, you can pull their specific connection string value and load it into the constructor as your doing above. A sample XML structure could be as follows:
<connections>
<connection userID="12345">Data Source=servA;Initial Catalog=db123;User ID=jSmith password=pass1</connection>
<connection userID="43532">Data Source=servB;Initial Catalog=db456;User ID=rJSmith password=abc321</connection>
</connections>
If all that is changing is the user, pass, catalog, and datasource values and the remainder of the connection string is static, you could just store these individual values as opposed to the entire connection string and then inject those dynamically to build the connection string at runtime.
Reading the XML is not difficult when using something like LINQ to XML which would allow you to query the XML file and get a specific connection string by the userID field. A good reference for LINQ to XML is at the following: http://msdn.microsoft.com/en-us/library/bb387098.aspx
OK here my piece of code
MySqlConnection conn = new MySqlConnection("Userid=root;pwd=root;port=3306;host=localhost;database=test");
conn.Open();
Due to some issue with the new version of the devart connector i'm using i have to add a line of code OldCompatibility.BinaryAsString = true;
everywhere in my code as shown below
OldCompatibility.BinaryAsString = true;
MySqlConnection conn = new MySqlConnectio("User id=root;pwd=root;port=3306;host=localhost;database=test");
conn.Open();
But the problem is i have to make this change all over my application which have many pages with this piece of code.So is there any way to do this globally so that i dont have to make this change all over my application.
i'm using devart connector 6
Assuming that your connection is remotely similar each time; don't. Keep all your connection logic in one shared method, and use that instead of repeating the connection code everywhere.
public static MySqlConnection Connect() {
OldCompatibility.BinaryAsString = true;
MySqlConnection conn = new MySqlConnection("User id=root;pwd=root;port=3306;host=localhost;database=test");
conn.Open();
return conn;
}
MySqlConnection is your custom class if you put OldCompatibility.BinaryAsString = true in the constructor of MySqlConnection then it would work
Change all your code at once with find and replace using regular expressions:
1.- Hit Ctrl+H to open the “Find and Replace” window Enter your search, replace line breaks with “\n” (no quotes)
2.- Expand “Find options” and check “Use”, select “Regular Expressions” (this also activates the right arrow next to the “Find what” box. It lists a few commands/shortcuts).
For example:
Type this on find:
{MySqlConnection conn = new MySqlConnection}
Then try this on replace:
OldCompatibility.BinaryAsString = true;\n\t\t\1 MySqlConnection conn = new MySqlConnection
This will find all the code that matches the search and add an additional line infront of it. Notice the place holder {...} being replaced with \1
You can use a factory method
public class FactoryMethods
{
public static MySqlConnection GetConfiguredConnection()
{
OldCompatibility.BinaryAsString = true;
MySqlConnection conn = new MySqlConnectio("User id=root;pwd=root;port=3306;host=localhost;database=test");
conn.Open();
return conn;
}
}
And assuming the connection is IDispose-able
using (var myConn = FactoryMethods.GetConfiguredConnection())
{
// Use your connection here
}
You should really consider #minitech's suggestion on using a method, but if you really can't change the code anywhere, there are only really two options I can see;
Extend MySQLConnection to a new class using the same name in another namespace, just changing the constructor to include your line. Then replace only the using line at the top of the file.
If that can't be done, implement a wrapper class in the same manner.
Both these options may fail to work (#1 if the class is final for example, and #2 if the class is passed as a parameter to any functions), but unless you can at least do a global search/replace or implement #minitech's suggestion with a method, I can't see any other way.