C# SQL connection string variable? - c#

In C# WinForms, where should I put my SQL connection string variable if I want to access it all over my application?
Right now I'm copy-pasting it wherever I'm using it.
//Sql connection string
SqlConnection con = new SqlConnection(#"Data Source=" + globalvariables.hosttxt + "," + globalvariables.porttxt + "\\SQLEXPRESS;Database=ha;Persist Security Info=false; UID='" + globalvariables.user + "' ; PWD='" + globalvariables.psw + "'");
SqlCommand command = con.CreateCommand();

You can simply use the app.config (or web.config) for that. It has a special section for connection-strings. See the MSDN-article about that. Then you can retrieve the string in code as use1515791 has already pointed out, like this:
ConfigurationManager.ConnectionStrings["NameOfConnectionStringInConfig"].ConnectionString

I rather not using app.config file, because it's not secure and hackable easily (every connection info is stored in plain text format here).
If I'm not using any of my DLLs, I place the SqlConnection in Program.cs with public getter and disabled setter. I make all the initializations in Program.cs, so it looks something like this:
static class Program
{
private static SqlConnection con;
internal static SqlConnection Con
{
get
{
return con = new SqlConnection(#"Data Source=" + globalvariables.hosttxt + "," + globalvariables.porttxt + "\\SQLEXPRESS;Database=ha;Persist Security Info=false; UID='" + globalvariables.user + "' ; PWD='" + globalvariables.psw + "'");
}
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
Now can access it (for example) from you Form1.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SqlCommand cmd = new SqlCommand();
cmd.Connection = Program.Con;
}
}
I've created a DLL to connect to SQL easily, check it here if you're interested.

Thats a rather general question imo.. depends on the application structure and so on. I tend to use a class "ApplicationContext" with properties for such things. However, maybe
ConfigurationManager.ConnectionStrings["whatever"].ConnectionString
is used a lot i think (add reference to System.Configuration)
Btw, if you use it "all over the place", don't you need an adapter class instead?
EDIT
public class DataAcces
{
private string Connectionstr;
public DataAcces()
{
this.Connectionstr = ConfigurationManager.ConnectionStrings["whatever"].ConnectionString;
}
public object ReturnSomething()
{
using(SqlConnection con = new SqlConnection(this.Connectionstr))
{
//do stuff to db and return something
}
}
}
and then when you need it
....
{
var whatYouNeed = (new DataAcces()).ReturnSomething();
}
typos happen :) this is the easiest to use i can come up with, not the best.

Related

c# - SQLite database is locked when inserting but good when using select [duplicate]

In C#, how to open an SQLite connection in WAL mode?
Here is how I open in normal mode:
SQLiteConnection connection = new SQLiteConnection("Data Source=" + file);
connection.Open();
// (Perform my query)
how about a factory approach to specify in the SQLiteConnection connetion string ?
for e.g
public static class Connection
{
public abstract SQLiteConnection NewConnection(String file);
}
public class NormalConnection : Connection
{
public override SQLiteConnection NewConnection(String file)
{
return new SQLiteConnection("Data Source=" + file);
}
}
public class WALConnection : Connection
{
public override SQLiteConnection NewConnection(String file)
{
return new SQLiteConnection("Data Source=" + file + ";PRAGMA journal_mode=WAL;"
}
}
The code is not tested, but I hope you can get the idea, so when you use it you can do like that.
SQLiteConnection conWal = new WALConnection(file);
conWAL.Open();
SQLiteConnection conNormal = new NormalConnection(file);
conNormal.Open();
The line below is what I was looking for, many thanks to Turbot whose answer includes it:
new SQLiteConnection("Data Source=" + file + ";PRAGMA journal_mode=WAL;")
Here is my less-than-perfect solution:
SQLiteConnection connection = new SQLiteConnection("Data Source=" + file);
connection.Open();
using (var command = new SQLiteCommand(sqliteConnection))
{
command.CommandText = "PRAGMA journal_mode=WAL";
command.ExecuteNonQuery();
}
// (Perform my query)
If you know something less verbose, I would be happy to hear about it!
Persistence of WAL mode
"Unlike the other journaling modes, PRAGMA journal_mode=WAL is persistent. If a process sets WAL mode, then closes and reopens the database, the database will come back in WAL mode."
http://www.sqlite.org/wal.html
If I understand it correctly, this means that you can set WAL mode for a database once, there's no need to set it on every connection.
You can do it with the command line shell for SQLite:
http://www.sqlite.org/sqlite.html

how to use retrieve and use setting value to connect to adatabase

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

c# program inserting rows in sql database

I know I have done this a few times before but for the life of me can't remember how.
I have a database I have created and I want to make a software that only inputs information into the database. The program works but my sql connection is the problem. So to test it out I basically tried to do it direct inserting hard-coded info but it still will not go. where am I going wrong?:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.Sql;
namespace InventoryTracker
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static void CreateCommand()
{
SqlConnection myConnection = new SqlConnection("User Id=Jab" + "password=''" + "Data Source=localhost;" + "Trusted_Connection=yes;" + "database=InventoryTracker;" + "Table=Inventory;");
try
{
myConnection.Open();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
SqlCommand myCommand = new SqlCommand("INSERT INTO Inventory (ItemName, SerialNumber, Model, Department, Quantity, Notes) " + "Values (string,string,string,string, 1, string)", myConnection);
}
}
}
Thank you in advance! :-)
Your sql connection string is messed up, you need semi-colons between all parameters and your parameters are messed up too. I.e., something like
"Server=localhost;Database=InventoryTracker;Trusted_Connection=True;"
You are mixing trusted mode and specifying the user id -- trusted connection means to use your windows login credentials.
TableName does not go in the connection string.
This site is great for connection string examples http://www.connectionstrings.com/sql-server-2008
You SQL command, "INSERT INTO Inventory (ItemName ..." is pretty messed up too. Should be something like
INSERT INTO Inventory (ItemName ...) values(#ItemName ...)
You then pass in the values like
myCommand.Parameters.Add("ItemName", SqlType.VarChar).Value = "Dozen Eggs";
See Insert data into SQL Server from C# code for a simple example
Just use the SqlConnectionStringBuilder class.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder.aspx
Instead of:
"User Id=Jab" + "password=''" + "Data Source=localhost;" + "Trusted_Connection=yes;" + "database=InventoryTracker;" + "Table=Inventory;");
Try:
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.UserID = "Jab";
builder.Password = "";
builder.DataSource = "localhost";
builder.InitialCatalog = "InventoryTracker";
// Don't put table name in your connection string
string connection_str = "Data Source = localhost ; uid = db_user; pwd = db_pass; database = db_name; ";
conn = new SqlConnection(connection_str);
conn.Open();
Try changing
"User Id=Jab" + "password=''" + "Data Source=localhost;" + "Trusted_Connection=yes;" + "database=InventoryTracker;" + "Table=Inventory;"
to
"User Id=Jab; " + "Password=''; " + "Data Source=localhost; " + "Trusted_Connection=yes; " + "Initial Catalog=InventoryTracker;"
(Changed upper/lower case, "Database" to "Initial Catalog", removed "Table" and added ";")
Also, you might want to try replacing "Data Source" by "Server".
Don't forget to call myCommand.ExecuteNonQuery to get it to actually execute your query. Without this, you are just creating a command, but not running it.

Apply same sql connection string to whole winform?

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.

Populate checkboxes via database

I have to populate checkboxes with data coming from database, but no checkboxes are showing on my page. Please let me know the correct way to do that. In C#, the page_load method I've written is this:
public partial class dbTest1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string Server = "al2222";
string Username = "hshshshsh";
string Password = "sjjssjs";
string Database = "database1";
string ConnectionString = "Data Source=" + Server + ";";
ConnectionString += "User ID=" + Username + ";";
ConnectionString += "Password=" + Password + ";";
ConnectionString += "Initial Catalog=" + Database;
string query = "Select * from Customer_Order where orderNumber = 17";
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(query, conn))
{
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
if (!IsPostBack)
{
Interests.DataSource = dr;
Interests.DataTextField = "OptionName";
Interests.DataValueField = "OptionName";
Interests.DataBind();
}
}
conn.Close();
conn.Dispose();
}
}
}
}
And in the .aspx, I have this:
<asp:CheckBoxList ID="Interests" runat="server"></asp:CheckBoxList>
Please tell me the correct way to accomplish this.
Although your question is already answered (via the connection string comments), I thought I'd chime in with a possible way to rewrite this. I'd started this off as a comment, but it got a bit long and unwieldy. Note that this doesn't directly answer your question, but it is something to consider for code cleanliness and a possible (likely very mild) performance boost on postbacks.
protected void Page_Load(object sender, EventArgs e)
{
// If we're in postback, let's not poll the database.
if (Page.IsPostback)
return; // Change this if you do need some postback processing here.
// I assume that in the real world you pull this info from web.config
string Server = "al2222";
string Username = "hshshshsh";
string Password = "sjjssjs";
string Database = "database1";
string ConnectionString = "Data Source=" + Server + ";";
ConnectionString += "User ID=" + Username + ";";
ConnectionString += "Password=" + Password + ";";
ConnectionString += "Initial Catalog=" + Database;
string query = "Select * from Customer_Order where orderNumber = 17";
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(query, conn))
{
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
// Going to assume that you're only getting 1 record
// due to apparent key (orderNumber = 17) in query?
// You can also consider "if (dr.Read())", but fundamentally
// they will do the same thing.
while (dr.Read())
{
Interests.DataSource = dr;
Interests.DataTextField = "OptionName";
Interests.DataValueField = "OptionName";
Interests.DataBind();
}
// I've excised the calls to .Close() and .Dispose(),
// as the using block covers them for you.
}
}
}
Why would we go this route?
In your original code, you were polling the database (and potentially looping, if my assumption about that being a single-record query was wrong) every page load, whether or not you were in postback. You weren't checking postback until you were inside the loop, where the damage was mostly already done. In the code I've listed, you short-circuit out of Page_Load() altogether if you're in postback. You can, of course, change that to an if/else and bracket the groups if you need some load-event processing on postbacks as well. This also simplified your in-loop code.
Your using blocks covered the disposal/closure of the connection for you. Thus, you do not need that additional code.
As OrbMan stated in the comments, hopefully in your actual code you're retrieving all the connection string info from your web.config file instead of hard-coding it, correct?
Final final unrelated note: This is a lot of data access code that newer versions of the .NET Framework simplify greatly with tools such as Entity Framework and LINQ-to-SQL. There are also 3rd-party data access layer tools (such as SubSonic and ActiveRecord) that will simplify this. Using tools such as those will greatly reduce the amount of code you're writing here -- and I'm guessing you're using quite a bit of similar code throughout your app as well, so those tools will provide you the developer with quite the productivity boost. (And much simpler down-the-road maintenance.)
Just food for thought.

Categories

Resources