commonly integrate a line of code at many places in c# - c#

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.

Related

C# not all code paths return a value when I declare a private string in a class method

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;
}

Best method to connect to SQL Server in C# WPF

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();
}

App.startup path does not work in my visual studio project?

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.

Proper format of nested "using" statements?

I have the following set of code:
using (OracleConnection conn = new OracleConnection(m_fceConn))
{
conn.Open();
using (OracleCommand cmd = new OracleCommand(m_sql, conn))
{
using (OracleDataReader reader = cmd.ExecuteReader())
{
reader.Read();
}
}
conn.Close();
}
Is there a better way to format this? Granted, later on I will probably be breaking out opening a connection, running a query, and closing the connection into separate functions at a later date but this nesting will still be there "behind the scenes" so to speak.
I read on another thread that I could format things like so:
using (OracleConnection conn = new OracleConnection(m_fceConn))
using (OracleCommand cmd = new OracleCommand(m_sql, conn))
But considering that I have code in between each of these statements I don't believe that I can omit the brackets like that. I'm just looking for the best/safest practice here since I'm still realtively new/noob to C#. Thanks.
I could be wrong, but I don't think you need to open the connection before passing it to OracleCommand. You just have to open it prior to executing a command. So you could write the above as:
using (OracleConnection conn = new OracleConnection(m_fceConn))
using (OracleCommand cmd = new OracleCommand(m_sql, conn))
{
conn.Open();
using (OracleDataReader reader = cmd.ExecuteReader())
{
reader.Read();
}
}
(you also shouldn't need to explicitly close either since disposing of the connection should close it automatically).
There's nothing special about the above code (other than it looks nice), it's just using normal C# rules that apply single commands to such blocks. it's the same as this:
if (...)
if (...)
dosomething(); // Look Ma, no curly braces
it's just that you're "stacking" multiple single statements.
What you have is properly formatted, though it's not necessary to call conn.Close() since the connection will be disposed (and thus closed) at the end of the using block that declared it.
You can, however, omit the brackets for the second statement, since the entirety of that statement is just another using block.
Your first using statement needs to have brackets, since you have the conn.Open() call there. The second and third can be stacked as you stated, which is pretty idiomatic C# (and preferred, in my case).
using (OracleConnection conn = new OracleConnection(m_fceConn))
{
conn.Open();
using (OracleDataReader reader = new OracleCommand(m_sql, conn).ExecuteReader())
{
reader.Read();
}
conn.Close();
}
EDIT
On second thought, don't do this. It wouldn't dispose of the command object. I will leave the answer here as an example of what NOT to do.

C# MySqlConnection won't close

I have an application that fires a mysql command (query) "show databases", the query works and returns properly but I can't close my connections. The user I used had 24 connections allowed at the same time so the problem popped up further down my program but reducing the allowed connections to 2 shows me that I can't even close the first query (which isn't in a loop). The code is the following:
protected override Dictionary<string, Jerow_class_generator.Database> loadDatabases()
{
MySqlConnection sqlCon = new MySqlConnection(this.ConnectionString);
sqlCon.Open();
MySqlCommand sqlCom = new MySqlCommand();
sqlCom.Connection = sqlCon;
sqlCom.CommandType = CommandType.Text;
sqlCom.CommandText = "show databases;";
MySqlDataReader sqlDR;
sqlDR = sqlCom.ExecuteReader();
Dictionary<string, Jerow_class_generator.Database> databases = new Dictionary<string, Jerow_class_generator.Database>();
string[] systemDatabases = new string[] { "information_schema", "mysql" };
while (sqlDR.Read())
{
string dbName = sqlDR.GetString(0);
if (!systemDatabases.Contains(dbName))
{
databases.Add(sqlDR.GetString(0), new MySQL.Database(dbName, this));
}
}
sqlCom.Dispose();
sqlDR.Close();
sqlCon.Close();
sqlCon.Dispose();
return databases;
}
P.S. The 'New MySQL.Database(dbName, this));' is my owm made class which only stores the DB structure, could be considered irrelevant.
The exact error I get is 'max_user_connections'. on the connection.open line of the next time a query needs to be fired.
Rather than keeping track of all the Open/Close/Dispose calls all over the place, I'd recommend just replacing all of those with using statements. This will make sure the expected scope of each object is clear and that it will be destroyed/disposed upon exiting that scope.
Close() nor using will help alone with your problem because ADO.NET is using its own connection pooling and connections are by default not closed until program is closed. There are few options to solve this, but consider performance implications and is this really desired behavior for your application.
Add ";Pooling=False" to your connection string.
SqlConnection.ClearPool Method
SqlConnection.ClearAllPools Method
For more information read: SQL Server Connection Pooling (ADO.NET)
Along with the using suggestions above, when creating your sqlDR variable you should use the CloseConnection command behavior to close the actual connection if that is your intended action. As noted in the documentation here.
When the command is executed, the associated Connection object is closed when the associated DataReader object is closed.
So your code to instantiate your reader would look like this:
//to instantiate your variable
MySqlDataReader sqlDR;
sqlDR = sqlCom.ExecuteReader(CommandBehavior.CloseConnection);
//closing your datareader reference here will close the connection as well
sqlDR.Close();
If you wrap all your code in a using block using the above method, you don't need any of those Close() or Dispose() methods other than the sqlDR.Close();
when use "using" key word what happen is.when the garbage collector activate it first dispose objects which was declred in using statement.
I recommend using connection pooling in combination with the MySqlHelper class, passing the connection string as the first argument. That allows MySQL to open the connection if necessary, or keep it open according to the pooling cfg, without you having to know about it.
I changed my code to use 1 connection and keep it open and when testing I came across an error that a datareader should be closed. Now since all my queries didn't close the dataReader object (I used dataTable.Load(cmd.ExecuteReader()).) I think the problem might be there.
Keeping 1 open connection worked perfectly so I don't know what caused the not closing problem. I gues it was the dataReader not closing by itself.
Close() will definitely help you close your.
using (MySqlConnection conn = GetConnection())
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "UserDetail";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
list.Add(new Album()
{
Id = Convert.ToInt32(reader["UId"]),
Name = reader["FirstName"].ToString(),
ArtistName = reader["LastName"].ToString()
});
}
}
}
}
In the above code, you can see one if condition before opening the connection it will help you to reuse your already open connections check below code.
if (conn.State != ConnectionState.Open)
{
conn.Open();
}

Categories

Resources