C# mdf database doesn't update on program startup - c#

I create simple example to create question easyer.
So in my c# project I create an mdf database with articles. Then I connect database in my program and read values from table articles. It gives me results, but not the latest.
If I have one result it showes me this one. Then I go in articles table to add one new article and run program again and in this case program showes me only the first one. But if I "Build solution" it finds all of them.
What I have to do? I wish, that program will have the latest result on startup.
SqlConnection cn = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True");
try
{
cn.Open();
string sqlQuery = "SELECT * FROM Articles";
SqlCommand sqlCommand = new SqlCommand(sqlQuery, cn);
SqlDataReader sqlDataRead = sqlCommand.ExecuteReader();
while (sqlDataRead.Read())
{
MessageBox.Show(Convert.ToString(sqlDataRead["ArticleLabel"]));
}
sqlDataRead.Close();
sqlDataRead.Dispose();
sqlCommand.Cancel();
cn.Close();
}
catch (Exception) { MessageBox.Show("Database error!"); Application.Exit(); }

If your MDF file has the property Copy To Output Directory set to Copy Always, then every time you build your application a fresh copy of the database file is copied from the project directory to the output Directory (BIN\DEBUG or BIN\RELEASE).
Of course this destroy any changes you have made in a previous run of your program
Change the property to Copy if Newer
Also, don't be fooled by what you see in the Server Manager Windows. The connections there could not point to the database in the Output directory but on the database in the Project Directory where you don't write anything.

Related

how to create a setup or installer file and adding MYSQL reference using visual studio C# and MYSQL for deploy my project into another system?

I'm develop a new project for Medical Laboratory by using visual studio C# WinForms for user interaction and MYSQL for database. After my successful build its running successfully in my windows machine. But the problem is when I install my project on another windows machine, the front end of UI running well but the database throw an error to me. The error is Authentication to host 'localhost' for user 'root' using method 'caching_sha2_password' failed with message: Unknown database 'login'. I think the error was I need to add MYSQL reference in my project. but I'm absolutely don't know how to do it. I'm really sorry to all coz I'm noob in C# and my English.
and literally thanks to all.
public partial class registration : Form
{
string connectionstring = "server = localhost; user id = root; database = login; password =
qwerty;";
MySqlConnection connection = new MySqlConnection(connectionstring);
MySqlCommand cmd;
connection.Open();
try
{
cmd = connection.CreateCommand();
cmd.CommandText = "ALTER TABLE register ADD UNIQUE INDEX(rgstrid);";
cmd.CommandText = "INSERT IGNORE INTO register(username, password,confirm) VALUES(#username,#password,#confirm)";
cmd.Parameters.Add("#username", MySqlDbType.VarChar).Value = rgstrusrnmtxtbx.Text;
cmd.Parameters.Add("#password", MySqlDbType.VarChar).Value = rgstrpswdtxtbx.Text;
cmd.Parameters.Add("#confirm", MySqlDbType.VarChar).Value = rgstrcnfrmtxtbx.Text;
DataTable table = new DataTable();
MySqlDataAdapter adapter = new MySqlDataAdapter();
adapter.SelectCommand = cmd;
adapter.Fill(table);
if (cmd.ExecuteNonQuery() == 1)
{
MessageBox.Show("Your Account resgistred Successfully", "information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Account saved Successfully","Success",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
catch (Exception)
{
throw;
}
finally
{
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
}
}
You probably need to include a reference to a library to talk to MySql, like the MySql.Data package. Adding it as a nuget reference should ensure the required files are installed with the rest of the application files.
Your installer also needs to install some software. The database engine itself if you are running a local database, but also a .net connector for the ado.net driver.
At least this is how we do it. You might be able to avoid some components depending how you are accessing the database.
When installing the database you should specify the root password. For example by giving the rootpasswd=qwerty parameter to the MySQLInstallerConsole.exe program.
Your install script also needs to setup the database, i.e. either run sql files to create any tables and fill it with data, or copy the database files themselves, or run some program to create the tables.

Dynamic Datasource Path 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

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

Changes do not get saved permanently into SQL Server Compact edition

I am having a weird problem. I am using vs2012 to connect to SQL Server CE and executing some insert queries.
public void EstablishConnection()
{
connection = new SqlCeConnection("Data Source=DataDump.sdf;Persist Security Info=False;");
try
{
connection.Open();
Console.WriteLine("Connection Successful");
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
public void AddRecord(string link,string content)
{
int num = 0;
var command = new SqlCeCommand("INSERT INTO Webpages(Link,Data) VALUES('"+link+"','"+content+"');",connection);
num = command.ExecuteNonQuery();
Console.WriteLine("Command Successful rows affected"+num);
var cmd2 = new SqlCeCommand("SELECT * FROM Webpages",connection);
SqlCeDataReader reader = cmd2.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader[0]);
Console.WriteLine(reader[1]);
}
}
However I am having the problem that once VS is closed and when later I open it to display the data, the data is gone as it was never saved
How is that possible when it is clear then it executed the query?
It is a common scenario.
You have your database file listed between your project items.
Its property Copy to Output directory is set to Copy Always.
Now, you run your debug session with VS. The compile is succesfull and VS copies your sdf file from the project folder to the current output directory (BIN\DEBUG).
Your code runs smoothly and inserts the data in your database file (on the output directory).
You stop and restart the debug session to fix something, but, at restart, the VS recopies the empty file from the project folder to the output directory.
To break this circle, set Copy to Output Directory to Copy Never (or Copy if Newer)
EDIT Another source of confusion is due to the use of SERVER EXPLORER to view the contents of your database file. If the server explorer use a connection string that points to the database file in the project folder you never see the changes made to the database file in the Output Directory.
You should create two connections in Server Explorer, one named DEBUG DataDump that points to PROJECTFOLDER\BIN\DEBUG. You could use this connection to check the data inserted during debug or for other debugging tasks. Another one, called DISTRIBUTION DataDump, points to the file in the project folder and you make here your schema changes needed for the distribution of your app.
Said that, keep in mind that your code has a BIG problem. It is called Sql Injection
A parameterized query will avoid quotations problems and remove the Sql Injection
int num = 0;
var command = new SqlCeCommand("INSERT INTO Webpages(Link,Data) " +
"VALUES(#lnk, #cnt)",connection);
command.Parameters.AddWithValue("#lnk", link);
command.Parameters.AddWithValue("#cnt", content);
num = command.ExecuteNonQuery();
set Copy to Output Directory property as Copy if newer for your sdf file
it seems now you have set it as copy always which result :
The database file is copied from the project directory to the bin
directory every time that you build your application. Any changes made
to the data file in the output folder are overwritten the next time
that you run the application.

OleDbCommand.ExecuteNonQuery() does not save changes in ms access database

I have .mdb database, and code like this:
using (OleDbConnection connection = new OleDbConnection(myConnectionString))
{
using (OleDbCommand cmd = connection.CreateCommand())
{
cmd.CommandText = "UPDATE myTab SET col2 = #val1 WHERE col1 = #val2";
cmd.Parameters.AddWithValue("#val1", 0);
cmd.Parameters.AddWithValue("#val2", -1);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
}
}
I get data from db, change it in my gui programm, then save it in db. Changes saves, but not in db (I don't know where), so when I run program, change data, close program, then again run - changes remain, but when I open db (not in programm), there are no changes saved, and again run - all changes disappear.
PS: when I commit changes, then run program several times, all changes disappear too, after (3-4 runs)
When we we add .mdb in project root in VS ,when change structure ,VS default delete .mdb file in debug folder and replace new file; now you can change this defult :
1- right click .mdb file and select option
2- set Copy To Output Directory to Do Not Copy
It is most likely the WHERE clause of your update statement isn't locating any records to update.
http://weblogs.asp.net/stevewellens/archive/2009/10/16/why-sql-updates-fail-three-reasons.aspx

Categories

Resources