Dynamic Datasource Path C# - c#

I created an app where a combobox is bound with an Access Database. The application was working fine on my computer because the source path in the connectionstring I defined was related to my computer. I copied the project folder to another computer which gives error of not finding the database at the specified location.
Can I dynamically set the path from a textbox or some other input? Can I call a database from the application where the source path doesn't matter. Even when I refer to Resources.Database1 it still gives full path to application folder for my computer which doesn't work on another computer. Any idea would be appreciated. Thanks!
My code is the following:
private void button1_Click(object sender, EventArgs e)
{
OleDbCommand command = new OleDbCommand();
command.CommandType = CommandType.Text;
command.CommandText = "INSERT INTO SubrubDatabaseT(SuburbName,DeliveryTime) values('" + textBox1.Text + "','" + textBox2.Text + "')";
OleDbConnection connect = new OleDbConnection();
connect.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\WoolsValley\Desktop\Database1.accdb ;
Persist Security Info = False; ";
connect.Open();
command.Connection = connect;
command.ExecuteNonQuery();
MessageBox.Show("Data Saved Successfully");
connect.Close();
}

For your case, the solution is to use an App.config (or Web.config depending on the type of the project you are developing) file and put all the settings there. Then if the path doesn't exist, you can still change it to an existing one in this file, and it will not be necessary to recompile the application.
This is the main use of these lind of files, to add there any settings that could change on the users machines or when the application is published and it may need little adjustments, as in this case, and it may not be needed to recompile for every computer the application runs.

As you mentioned yourself, you can simply have a text box for the file path or maybe an OpenFileDialog component to select the file. You then pass that in the connection string:
//GetFileSource() a method that gets the source from somewhere, like a textbox or a configuration entry in app.config.
var fileSource = GetFileSource();
connect.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileSource + ";Persist Security Info = False;";
What's equally important is that you make sure the file actually exists at the destination.

You could create a method that searches the users folder for data files or let the user specify a data file on startup and save that to the users profile directory. There are many ways to do this and which way you choose depends on factors like how is the data file copied to the users PC, are there many data files possible, etc.
If the data file only exists with the app, there is only one data file possible, and the data file is copied/created at deployment time (ie. when you run the MSI) then put it in the app.config instead as a connection element. See Connection Strings and Configuration Files.
First thing is to always use parameterized queries. See https://msdn.microsoft.com/en-us/library/system.data.oledb.oledbcommand.parameters(v=vs.110).aspx
Remarks
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement or a stored procedure called by an OleDbCommand when CommandType is set to Text. In this case, the question mark (?) placeholder must be used.
Your code refactored with using statements and parameterized inputs.
// get file from the drop down
var filePath = getSelectedDataFile();
using (OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath))
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO SubrubDatabaseT(SuburbName,DeliveryTime) values(?,?)";
cmd.Parameters.Add(new OleDbParameter("#suburbName", OleDbType.VarChar)).Value = textBox1.Text;
cmd.Parameters.Add(new OleDbParameter("#deliveryTime", OleDbType.VarChar)).Value = textBox2.Text;
con.Open();
cmd.ExecuteNonQuery();
}
Note that:
OleConnection and OleDbCommand are wrapped in using blocks so they are disposed/cleaned up even when an exception occurs.
Parameters are now used instead of hard coding the string values
Parameters use the correct data types

Related

Cannot add sqlite db file to Word adding deployment

I developed C# Word add-in which populates some data from database file. It is working fine while I am running through Visual studio running. But if I publish it cannot connect to database.
Here is how I get data from database:
SQLiteConnection con = new SQLiteConnection(ThisAddIn.connectionString);
con.Open();
var command = con.CreateCommand();
command.CommandText =
#"
SELECT *
FROM JK
WHERE article_number = $article_number
";
command.Parameters.AddWithValue("$article_number", textFromDoc);
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var title = reader.GetString(2);
var article = reader.GetString(3);
ResultForm resultForm = new ResultForm();
resultForm.setArticle(title, article);
resultForm.ShowDialog();
}
}
public static string connectionString = #"Data Source=E:\projects\c#\TBPWordAddin\WordAddIn1\codexes.db";
Am I doing something wrong or do I need to include file in another way? Any help will be appreciated.
Also I tried publishing using Visual studio installer and it connected to database but the add in didnot lounched on other computers.
The connection string contains an absolute path which can be changed after publishing an application. I'd suggest using a relative path instead - in that case you will be able to find the Db easily. You may check out the following threads for more information on such kind of issues:
Connection string with relative path to the database file
How to give relative path of connection string or data source in windows form application
But if I publish it cannot connect to database.
Make sure the Db path (see the connection string) corresponds to the hardcoded value in the application used.

Compare tables between two MDF files

I am attempting to synchronizing tables in two different .MDF files. After successfully creating a datatable for the first file I get an error when trying to create the second:
Cannot attach file 'E:\JVT-Inventory.mdf' as database 'JVT-Inventory' because this database name is already attached with file 'C:\Database\JVT-Inventory.mdf'
I have created separate procedures for each connection to create the tables then disposed the connection. Both the datatable and adapter are global variables to be used in my routines to compare the tables. None of the online research seems to apply to what I am trying to accomplish.
string conString;
conString = "Data Source=(LocalDB)\\v11.0;attachdbfilename=" + #txtPath.Text + ";Initial Catalog=JVT-Inventory;integrated security=True";
using (SqlConnection connection = new SqlConnection(conString))
{
daRemote = new SqlDataAdapter("SELECT * FROM tblProduct ORDER BY keyPartNo", connection);
SqlCommandBuilder cbRemote = new SqlCommandBuilder(daRemote);
daRemote.Fill(dtRemote);
connection.Dispose();
This connection is made to a file on a flash drive.
The issue appears to be that the MDF file remains open until I exit the application. My question now is, how do I close the MDF file from within my application?
After searching many articles about working with databases I figured out the follow:
SqlConnection cnRemoteBye = new SqlConnection();
SqlCommand cmdRemoteBye = new SqlCommand();
cnRemoteBye.ConnectionString = #"Data Source=(LocalDB)\v11.0;Integrated Security=True";
cmdRemoteBye.CommandText = "ALTER DATABASE [JVT-Inventory] SET OFFLINE WITH ROLLBACK IMMEDIATE \n\r exec sp_detach_db #dbname = [JVT-Inventory]";
cmdRemoteBye.Connection = cnRemoteBye;
cnRemoteBye.Open();
cmdRemoteBye.ExecuteNonQuery();
cnRemoteBye.Close();

How to save DataSet after adding data?

Yes, I know that this questions has been asked at least 5-10 times in here, but I can't for the life of me get any of the methods to save the data.
The idea is to create a new row in table Companies in column Name (there is only one column) with value "asdf"`.
I've tried combinations of the following:
DatabaseDataSetTableAdapters.CompaniesTableAdapter adapter = new DatabaseDataSetTableAdapters.CompaniesTableAdapter();
DatabaseDataSet ds = new DatabaseDataSet();
adapter.Insert("asdf");
adapter.Fill(ds.Companies);
adapter.Update(ds.Companies);
ds.AcceptChanges();
ds.Companies.AddCompaniesRow("asdf");
ds.Companies.AcceptChanges();
ds.Companies.AddCompaniesRow("asdf");
ds.Companies.Rows[0]["Name"] = "asdf";
adapter.Update(ds.Companies);
I'm using C# WPF .NET 4.5.1
It does add the data, but it doesn't save it when I exit the program - I know that it adds data, because if I call this method twice it crashes, because the value is no longer unique.
Here is the DatabaseDataSetTableAdapters:
http://pastebin.com/gNsaRFD5
This did not work either:
SqlConnection myConnection = new SqlConnection(global::AliBabaMailer.Properties.Settings.Default.DatabaseConnectionString);
myConnection.Open();
SqlCommand myCommand = new SqlCommand("INSERT INTO Companies (Name) " +
"Values ('string')", myConnection);
myCommand.ExecuteNonQuery();
myConnection.Close();
Ok so your problem is the Connection String:
Properties.Settings.Default.DatabaseConnectionString
This connection string is of the form:
“Data Source=ServerName;AttachDbFilename=|DataDirectory|\DataBaseName;Integrated Security=True”
The |DataDirectory| is usually here:
C:\Users\UserName\AppData
When you save the data it is being saved to a database file at `|DataDirectory| location but when you try to view the data using Server Explorer you are trying to view from a database file which is in your project's folder, that is why If you try to save and then view the data on run time it will work fine because then you will be querying the same database you are storing your data into.
|DataDirectory|:
|DataDirectory| (enclosed in pipe symbols) is a substitution string that indicates the path to the database. It eliminates the need to hard-code the full path which leads to several problems as the full path to the database could be serialized in different places. |DataDirectory| also makes it easy to share a project and also to deploy an application.
For example, instead of having the following connection string:
"Data Source= c:\program files\MyApp\Mydb.sdf"
Using DataDirectory, you can have the following connection string:
“Data Source = |DataDirectory|\Mydb.sdf”
To set the DataDirectory property, call the AppDomain.SetData method. If you do not set the DataDirectory property, the following default rules will be applied to access the database folder:
For applications that are put in a folder on the user's computer, the database folder uses the application folder.
For applications that are running under ClickOnce, the database folder uses the specific data folder that is created.
Link
Coding Advice:
Try to dispose your Command and Connection Objects like this:
using(SqlConnection myConnection = new SqlConnection(global::AliBabaMailer.Properties.Settings.Default.DatabaseConnectionString))
using(SqlCommand myCommand = new SqlCommand("INSERT INTO Companies (Name) " + "Values ('string')", myConnection))
{
myConnection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}

how to set a path to the local directory in c# for .mdf database in Service.cs file

Do you know how to set a path to the local directory in c# when trying to set a path for a datbase in the service.cs file? (I am developing in VS2010)
I have developed a winforms program that uses a .mdf (SQL Server) database. The program communicates to the database through a SQL Server connection string.
I have hard coded the path of the db at the mo but would like to know how to point to the current directory.
I have seen online
AttachDbFilename =|DataDirectory|\Database.mdf
But it doesn't seem to work for me as the connection will not open.
Also I have tried using Environment.CurrentDirectory however that with CurrentDirectory is weirdly not in the namespace.
If the file is in the same assembly folder you can use this
string folder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings["myCS"].ConnectionString = config.ConnectionStrings.ConnectionStrings["myCS"].ConnectionString.Replace("#folder#",folder);
config.Save(ConfigurationSaveMode.Full, true);
Go to solution Explorer >> right click the project>> click properties>> go to setting tab>>Make name: MyConnectionString Type:(connection string) Scoper: Application
and select the DB(Db should be kept in your |DataDirectory| along with your dblog)>> select that DB. >> save it.
Then use this code for connection
SqlCeConnection cnn = new SqlCeConnection(Properties.Settings.Default.MyConnectionString);
You have to give the namespace: using System.Data.SqlServerCe;
hope this will solve.
Accept if this works and close the question
there is a way to get the .mdf and .ldf of a databese, through the code that have worked for me, to do that, open a connection to the database using the connection string, prepare SQL command, with the query
select physical_name from sys.database_files where type = 0
then execute the command, and by the way, type = 0, is for mdf, and type = 1 is for ldf, you can also use this query directly in the SSMS
this is the sample code, keep in mind that you need to get the connection string
string _mdfCommand = "select physical_name from sys.database_files where type = 0";
string _ldfCommand = "select physical_name from sys.database_files where type = 1";
SqlCommand GetSQLData = new SqlCommand();
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
GetSQLData.CommandText = _mdfCommand;
GetSQLData.Connection = connection;
string mdf_Path= (string)GetSQLData.ExecuteScalar();
GetSQLData.CommandText = _ldfCommand;
GetSQLData.Connection = connection;
string ldf_Path= (string)GetSQLData.ExecuteScalar();
connection.Close();

Making a copy of an azure database

I need to make a copy of an azure database but I don't have access to any management tools, only a connection string.
I know that to use the CREATE DATABASE x AS COPY OF y command I need to be in the master database but I don't know how to tell Azure to run my command from there. For example, I have this code:
var commandText = "CREATE DATABASE foobar AS COPY OF " + database;
var connectionString = <my_connection_string>;
using (var conn = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(commandText, conn))
{
cmd.CommandType = CommandType.Text;
conn.Open();
cmd.ExecuteNonQuery();
}
}
which fails with error "User must be in the master database" - as I expected.
However my connection string is not valid for the master database, so how do I execute this command from the master database? If I was in SQL Management Studio I would just do:
use master
CREATE DATABASE x AS COPY OF y
Is there any way of emulating that in my code?
Change your connection string to access the master database instead of your regular one. It's as simple as that and the only solution.

Categories

Resources