I'm trying to make a method in my Admin class (for a small course project) which should INSERT a new movie into my database.
I don't get any errors, but the new data is not inserted into the database.
Here is my code:
public void AddMovieToDB(int mCodeLable, string title, int yearOfMovie, int lengthInMinutes, string dvdOrVhs, string genreOfMovie)
{
int movieCodeLable = mCodeLable;
string movieTitle = title;
int year = yearOfMovie;
int length = lengthInMinutes;
string typeOf = dvdOrVhs;
string genre = genreOfMovie;
string connectionString = #"Data Source=|DataDirectory|\VideoStoreDB.sdf";
SqlCeConnection connection = new SqlCeConnection(connectionString);
connection.Open();
SqlCeCommand command = new SqlCeCommand(
"INSERT INTO Movie(MovieCodeLable, Title, Year,
LengthMinutes, TypeOf, Genre)
VALUES(#mcl, #title, #year, #length, #typeOf, #genre)", connection);
command.Parameters.AddWithValue("#mcl", movieCodeLable);
command.Parameters.AddWithValue("#title", movieTitle);
command.Parameters.AddWithValue("#year", year);
command.Parameters.AddWithValue("#length", length);
command.Parameters.AddWithValue("#typeOf", typeOf);
command.Parameters.AddWithValue("#genre", genre);
command.ExecuteNonQuery();
connection.Close();
Console.WriteLine("Movie added to the DB!");
}
And this is how i call it from the Main:
Admin admin1 = new Admin();
admin1.AddMovieToDB(0151, "Play ball!", 2012, 124, "DVD", "Drama");
This is a possible scenario.
Your connection string use |DataDirectory|. This means that at RUNTIME, inside VS debug session, the substitution string points to the folder BIN\DEBUG where is located the file sdf copied by VS when it starts the debug session (Check the property Copy to Output directory for your sdf file).
The insert works flawlessy. (you can check that looking at the return value of ExecuteNonQuery()).
You stop the debug and check the content of your table using Server Explorer but you don't find anything.
The only problem is the connection used by your Server Explorer window that point to a different database. The one in the project folder.
I suggest to create two connections on Server Explorer. Leave the current one as is (so this db is your main empty copy ready to be deployed with your application) and add another connection that points to the db in the PROJECTFOLDER\BIN\DEBUG where is located the db used during the debug sessions (Right click 'Add Connections', Select Sql Server Compact Edition and browse to the BIN\DEBUG folder)
Related
I've created the simple program that is connected with one database. The connection with SQL db is perfect. I can insert data now. I use Object Explorer SQL Server.
Now my issue: I cannot use the program if the path to the mdf file isn't "C:/folder/repair.mdf". I want my program to be independent from the C disk, because I should send this program (vs files, etc) to other people.
How can I write the correct path and where can I do that?
You can try the following steps to move your db file to other disk and read the correct path.
First, please close all the connection about the database.(Execute the following query in Query Editor window )
ALTER DATABASE School SET SINGLE_USER WITH ROLLBACK IMMEDIATE
Second, you could copy your db file from the C disk to your project.(Include mdf and ldf file)
Finally, we can execute the following c# code to connect to the db file.(I place the db file in project\bin\debug\school.mdf).
private void button1_Click(object sender, EventArgs e)
{
string dbpath = System.AppDomain.CurrentDomain.BaseDirectory+"School.mdf";
string connstr = string.Format("Data Source=yourdatasource;AttachDbFilename={0};Integrated Security=True;", dbpath);
SqlConnection connection = new SqlConnection(connstr);
connection.Open();
string sql = "select * from Student";
SqlCommand command = new SqlCommand(sql,connection);
SqlDataReader reader = command.ExecuteReader();
while(reader.Read())
{
Console.WriteLine(reader[0].ToString());
}
connection.Close();
}
Note: The dbpath is a absolute path, which can specify to the corresponding path in different computers.
I am building a inventory based application that can be directly run from any pc without any installation and so i am using SQL CE.. On Start, I am checking if database is present. If Not i am creating new database as :
try
{
string conString = "Data Source='ITM.sdf';LCID=1033;Password=ABCDEF; Encrypt = TRUE;";
SqlCeEngine engine = new SqlCeEngine(conString);
engine.CreateDatabase();
return true;
}
catch (Exception e)
{
//MessageBox.Show("Database Already Present");
}
The database is created properly and i can access the database to create tables as well.. The Problem i am facing is - I am inserting and updating records in windows form on button click with code :
using (SqlCeConnection connection = new SqlCeConnection(DatabaseConnection.connectionstring))
{
connection.Open();
String Name = NameTxt.Text.ToString();
String Phone = PhoneTxt.Text.ToString();
double balance = Double.Parse(BalanceTxt.Text.ToString());
String City = CityTxt.Text.ToString();
string sqlquery = "INSERT INTO Customers (Name,Phone,Balance,City)" + "Values(#name,#phone, #bal, #city)";
SqlCeCommand cmd = new SqlCeCommand(sqlquery, connection);
cmd.Parameters.AddWithValue("#name", Name);
cmd.Parameters.AddWithValue("#phone", Phone);
cmd.Parameters.AddWithValue("#bal", balance);
cmd.Parameters.AddWithValue("#city", City);
int x = cmd.ExecuteNonQuery();
if (x > 0)
{
MessageBox.Show("Data Inserted");
}
else
{
MessageBox.Show("Error Occured. Cannot Insert the data");
}
connection.Close();
}
and Updation Code is
using (SqlCeConnection connection = new SqlCeConnection(DatabaseConnection.connectionstring))
{
connection.Open();
int idtoedit = select_id_edit;
String Name = NameEditTxt.Text.ToString();
String Phone = metroTextBox1.Text.ToString();
String City = CityEditTxt.Text.ToString();
string sqlquery = "Update Customers Set Name = #name, Phone = #phone,City = #city where Id = #id";
SqlCeCommand cmd = new SqlCeCommand(sqlquery, connection);
cmd.Parameters.AddWithValue("#name", Name);
cmd.Parameters.AddWithValue("#phone", Phone);
cmd.Parameters.AddWithValue("#id", idtoedit);
cmd.Parameters.AddWithValue("#city", City);
int x = cmd.ExecuteNonQuery();
if (x > 0)
{
MessageBox.Show("Data Updated");
}
else
{
MessageBox.Show("Error Occured. Cannot Insert the data");
}
loadIntoGrid();
connection.Close();
}
Whenever i execute code for inserting and updating records - Records are reflected in datagrid filled with adapter from database table. But once i restart the application, values do not appear in database. Once in a million, values are reflected in database. I cannot understand the reason behind this issue.
I have reffered to these articles :
C# - ExecuteNonQuery() isn't working with SQL Server CE
Insert, Update, Delete are not applied on SQL Server CE database file for Windows Mobile
But since i am creating database programmatically - It is getting created directly to bin/debug directory and i cannot see it in solution explorer in visual studio for changing copy options
You probably rewrite your database file with a blank copy from your project.
See this answer. You should not store your database in a bin folder, rather you should find a place in user's or public profile in AppData or another folder, depending on your needs.
The connection string would look like this:
<connectionStrings>
<add name="ITMContext" connectionString="data source=|DataDirectory|\ITM.sdf';LCID=1033;Password=ABCDEF; Encrypt = TRUE;" providerName="System.Data.SqlServerCe.4.0">
You shuld deploy your db file with your custom code run at app's starup to a chosen location, see this ErikEJ blog: http://erikej.blogspot.cz/2013/11/entity-framework-6-sql-server-compact-4_25.html
private const string dbFileName = "Chinook.sdf";
private static void CreateIfNotExists(string fileName)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
// Set the data directory to the users %AppData% folder
// So the database file will be placed in: C:\\Users\\<Username>\\AppData\\Roaming\\
AppDomain.CurrentDomain.SetData("DataDirectory", path);
// Enure that the database file is present
if (!System.IO.File.Exists(System.IO.Path.Combine(path, fileName)))
{
//Get path to our .exe, which also has a copy of the database file
var exePath = System.IO.Path.GetDirectoryName(
new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);
//Copy the file from the .exe location to the %AppData% folder
System.IO.File.Copy(
System.IO.Path.Combine(exePath, fileName),
System.IO.Path.Combine(path, fileName));
}
}
Check also this post.
You have several options to change this behavior. If your sdf file is
part of the content of your project, this will affect how data is
persisted. Remember that when you debug, all output of your project
(including the sdf) if in the bin/debug folder.
You can decide not to include the sdf file as part of your project and manage the file location runtime.
If you are using "copy if newer", and project changes you make to the database will overwrite any runtime/debug changes.
If you are using "Do not copy", you will have to specify the location in code (as two levels above where your program is running).
If you have "Copy always", any changes made during runtime will always be overwritten
The database file in your project can be different when debugging or not. Check also this answer. You might be writting your records to another copy of the database file.
I would like some help with my Visual Studio C# code with inserting unicode strings into a SQLite database.
Below is my test code to write a test string to the database:
string testStr = "á Á ñ ç é á";
SQLiteConnection mydataConnection = new SQLiteConnection(); // setup new sql connection obj
try
{
//// SQLite DB
mydataConnection.ConnectionString =
"Data Source=C:\\Users\\John\\Desktop\\location.db; Version=3; UseUTF16Encoding=True;Synchronous=Normal;New=False"; // set up the connection string
mydataConnection.Open(); // open the connection to the db
SQLiteCommand myCmd = new SQLiteCommand(); // create a new command object
myCmd.Connection = mydataConnection; // whats its connected to, see above connection string
SQLiteParameterCollection myParameters = myCmd.Parameters; // good pratice to use parameters to pass data to db
myParameters.AddWithValue("#name", testStr); //
myCmd.CommandText = "INSERT INTO location (name) VALUES (#name)";
myCmd.ExecuteNonQuery();
}
catch (SQLiteException d)
{
string myerror = "Database Error" + d;
MessageBox.Show(myerror);
}
finally // good pratice to close db connection in a finally so exceptions dont leave open.
{
mydataConnection.Close();
}
When I view the database/table (using SQLite Administrator) the string looks like this:
á à ñ ç é á
As a test, I can copy & paste the string direct into the database using SQLite Administrator and the string is saved and can subsequently be viewed OK.
I have tried toggling "UseUTF16Encoding=True;" True / False - no difference.
Any ideas what I'm doing wrong.
This problem turned out to be an issue with the SQLite Administrator app I was using to view/check the db/data. Seems it was this app that would not display the characters correctly when inserted by my code. Strangely though if you used the SQLite Administrator app to add the test text directly (by copy & pasting the test string into the table/field) it would display, save & subsequently view OK. Anyway now using SourceForge SQLite Database Browser to check my code writes correctly and all seems in order.
Many thanks for anyone who took the time to comment, hope this is of help to someone else.
You can try with this code
byte[] encod = Encoding.Default.GetBytes(testStr );
string result = Encoding.UTF8.GetString(encod);
myParameters.AddWithValue("#name", result);
I want to insert values in "Navn" row and "Varenr" row in the DB table, when I'm clicking on a button. I have following code:
private void button2_Click(object sender, EventArgs e)
{
using (SqlConnection cn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Produkt.mdf;Integrated Security=True"))
{
try
{
SqlCommand cm = new SqlCommand();
cm.Connection = cn;
string col1 = textBox2.Text;
string col2 = textBox3.Text;
//generate sql statement
cm.CommandText = "INSERT INTO ProduktTable (Navn,Varenr) VALUES (#col1,#col2)";
//add some SqlParameters
SqlParameter sp_add_col1 = new SqlParameter();
sp_add_col1.ParameterName = "#col1";
//data type in sqlserver
sp_add_col1.SqlDbType = SqlDbType.NVarChar;
//if your data type is not number,this property must set
//sp_add_col1.Size = 20;
sp_add_col1.Value = textBox2.Text;
//add parameter into collections
cm.Parameters.Add(sp_add_col1);
//in your insert into statement, there are how many parameter, you must write the number of parameter
SqlParameter sp_add_col2 = new SqlParameter();
sp_add_col2.ParameterName = "#col2";
//data type in sqlserver
sp_add_col2.SqlDbType = SqlDbType.NVarChar;
//if your data type is not number,this property must set
//sp_add_col2.Size = 20;
sp_add_col2.Value = textBox2.Text;
//add parameter into collections
cm.Parameters.Add(sp_add_col2);
//open the DB to execute sql
cn.Open();
cm.ExecuteNonQuery();
cn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
But unfortunately, my data table is still empty:
I have set a breakpoint on the ExecuteNonQuery function, and it is triggered, when pressing on the button:
My table definition:
Your connection string is causing this:
Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Produkt.mdf;Integrated Security=True"
|DataDirectory| Your database that is being updated in this method is in your App Data Directory while the one you are trying to retrieve data from is in your project folder...
|DataDirectory| is a substitution string that indicates the path to the database. DataDirectory also makes it easy to share a project and also to deploy an application. For my PC my App Data Directory is:
C:\Users\MyUserName\AppData\...
If you browse to this location and then go to following folders
...\Local\Apps\2.0\Data
You will be able to find your particular application directory probably stored with your assembly name, or some hash when you go there you will find it the database there is being updated just fine. This connection string is best for deployment.
You can also try this:
If you notice that Server Explorer is detecting all the databases on my PC and you can notice that there are couple of MINDMUSCLE.MDF files but all are at different paths, this is because there is one file in DEBUG directory, one in my PROJECT directory, one in my APP DATA directory. The ones starting with the numbers are stored in my APP DATA directories... If you select your respective database file and then run the SELECT query against it, you will get your data.
I made a tutorial some time ago. May be it will help you:
Check the value that ExecuteNonQuery is returning. It should return an int with the number of records affected by the SQL statement.
If it comes back with a value other than 0, then you know a record is being inserted somewhere. Before you close the connection, run a SQL query against the table to select all of the records and see if they come back through the code.
SELECT * FROM ProduktTable
If you get some records, then you may want to double check the database you're looking at through the IDE and the one your inserting records into through the code. It could be possible that you've got two different databases and you're querying one while inserting into another one.
Those are the steps that I would go through to help narrow down the issue and sounds like something I've probably done before. I hope it helps!
Whenever I run the following code I get the expected output
private int NewBorrower(string givenName, string surname)
{
int returnValue = 0;
using (conn)
{
conn.Open();
string sql = "AddBorrower";
cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#givenName", SqlDbType.NVarChar).Value = givenName;
cmd.Parameters.Add("#surname", SqlDbType.NVarChar).Value = surname;
SqlParameter id = cmd.Parameters.Add("#id", SqlDbType.Int);
id.Direction = ParameterDirection.ReturnValue;
try
{
cmd.ExecuteNonQuery();
returnValue = (int)cmd.Parameters["#id"].Value;
}
catch (Exception e)
{
Console.WriteLine("Commit Exception Type: {0}", e.GetType());
Console.WriteLine(" Message: {0}", e.Message);
}
}
return returnValue;
}
When run from the front end I get the results I want, but when I check the database it doesn't show up in the table.
For good measure this is also the stored procedure being used
CREATE PROCEDURE [dbo].[AddBorrower]
#givenName nvarchar(50),
#surname nvarchar(50),
#id int = NULL OUTPUT
AS
INSERT INTO llBorrowers (givenName, surname)
VALUES (#givenName, #surname);
SET #id = SCOPE_IDENTITY();
RETURN #id
I've tried using transactions on both the c# and sql sides, and that didn't work at all.
I should also mention that it is a local database, but I'm not sure that should affect it.
When you use the DataDirectory substitution string in a WinForms application, its real value changes depending on your debug or release configuration.
In DEBUG your DataDirectory points to PROJECTFOLDER\BIN\DEBUG (or x86 variation if it is the case).
So it is extremely easy to get fooled by this. You create a connection in server explorer but this connection is ignored by your code that works on a different database.
You could create another connection in Server Explorer and name it DebugConnection, still keeping the original one for schema changes while you use the DebugConnection to check if your code executes as expected
As a side note, keep particular attention to the property Copy To the Output Directory property on the MDF file if it is listed between the project items. If you set it to Copy Always every time you start a debug session a fresh copy of your db will be copied from the project directory to the output directory effectively destroying the updates executed by your code. I recommend to set it to Copy Never and handle manually the database schema changes
A reference: Where is DataDirectory
You may try creating a SQLTransaction in C# part
Also, try changing your code like -
//Just create a SQL connection - cmd = new SqlCommand(conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "AddBorrower";