Visual Studio Server Explorer show table data is blank - c#

I am working on a Winforms c# program with a service-based database. I have created a table called Books which is empty and currently has no records.
Using some code, I am inserting into the table values. For some reason, when clicking Show Table Data, it still shows as blank despite me having added a record.
I checked to see if the record was there (but hidden) by using a DataGridView with the source of its data being the Books table. I could see the record had been created, but for some reason is not showing in the Server Explorer's Show Table Data view.
Here is my code for inserting a new record into the table:
string query = "INSERT INTO Books (ISBN, Title, Authors, Publishers, Genre, Page_Count, Quantity) VALUES (#isbn, #title, #authors, #publishers, #genre, #page_count, #quantity)";
string connectionString = "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\LMSDB.mdf;Integrated Security=True";
// Establish connection with database
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Avoid SQL injection using parameters. Replace them with their real values
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#isbn", isbn);
command.Parameters.AddWithValue("#title", title);
command.Parameters.AddWithValue("#authors", authors);
command.Parameters.AddWithValue("#publishers", publishers);
command.Parameters.AddWithValue("#genre", genre);
command.Parameters.AddWithValue("#page_count", pageCount);
command.Parameters.AddWithValue("#quantity", quantity);
try
{
connection.Open();
if (command.ExecuteNonQuery() == 1)
{
// 1 Row affected. Success
Console.WriteLine("Book added to database successfully");
ClearControlValues();
}
}
catch (Exception ex)
{
MessageBox.Show("An error occured:\n" + ex.Message);
}
finally
{
connection.Close();
}
}
As you can see, the Show Table Data view is appearing blank, despite me knowing that there is a record as I can see it on a DataGridView
Is there something I'm missing as to why the record isn't appearing?
EDIT: Solved thanks to Steve who pointed out that the Server Explorer and my code had different connection strings. Having changed these around, I now have the intended result.

I made a test with your code, and data can be inserted successfully.
As Steve said, the problem lies in your connection string.
And you can find your connectionstring by following steps:
1.Right-click on the connection name and select Properties.
2.There is an item called Connection String in the Properties window.
As follows:
Daniel Zhang

Related

C# fill an access database from a dataset

I have a program which is supposed to open, edit, create and save access databases. For saving I copy an empty database with just the tables (just to avoid going through the hassle of creating every table and column etc) and try to fill it with values via the TableAdapterManager.UpdateAll method.
string _TemplateConnectString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};";
_connection = new OleDbConnection(string.Format(_TemplateConnectString, dlg.FileName));
_connection.Open();
DataSet1TableAdapters.TableAdapterManager tam=new TableAdapterManager();
tam.Connection = _connection;
try
{
tam.UpdateAll(dataset);
}
catch (System.Exception ex)
{
MessageBox.Show("Update failed");
}
It finishes with no exceptions but the values don't get inserted into the new database.
Also as far as I know the UpdateAll method only updates modified row so if I open some db and it inserts it's rows, it will not take them into account even though there are not in the database that I am trying to fill.
I have also tried filling the database with the ADODB and ADOX extensions but all the solutions I found with those was a lot of hardcoding and no regards for hierarchy, keys, etc.
Is there a way to force insert everything in the new database?
Is your template database in the Visual Studio project directory? It might have something to do with Visual Studio copying the database to the bin/debug or bin/release folder...
Try to use the right Data source database name, here an
example with an excel file:
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=c:\somepath\ExcelFile.xls;" & _
"Extended Properties=""Excel 8.0;HDR=Yes;"";"
A clumsy solution but it works. I iterate the tables of the dataset and save the via an sql string generator like this:
void SaveTable(DataTable dt)
{
string[] inserts;
try
{
inserts = SqlHelper.GenerateInserts(dt, null, null, null);
foreach (string s in inserts)
{
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = s;
cmd.Connection = _connection;
int n = cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
SaveOk = false;
}
}
I found the SqlHelper somewhere on this site, but completely lost where, unforunately. So here is the pastebin with it https://pastebin.com/iCMVuYyu

Datagridview doesn't refresh

I'm new to visual C# and I created a local database and added a datagridview that shows the contents of the database. The problem is that the datagridview doesn't refresh whenever I add something to the database. It only refreshes once I run my application again.
I tried changing the connectionstring from this:
SqlCeConnection cn = new SqlCeConnection(#"Data Source=C:\Users\Florence\Documents\Visual Studio 2012\Projects\WindowsFormsApplication1\WindowsFormsApplication1\Quality.sdf");
to this:
SqlCeConnection cn = new SqlCeConnection(Properties.Settings.Default.QualityConnectionString);
But then, the datagridview refreshes but the data doesn't store into the database.
Here is my insert statement:
try
{
SqlCeCommand exeSql = new SqlCeCommand("INSERT INTO [Read](Date,temperature,ph,conductivity,dissolvedOxygen) VALUES (#date,#tem,#ph,#con,#dis)", cn);
exeSql.Parameters.AddWithValue("#date", lblTime.Text);
exeSql.Parameters.AddWithValue("#tem", 1.5);
exeSql.Parameters.AddWithValue("#ph", 1.2);
exeSql.Parameters.AddWithValue("#con", 1.5);
exeSql.Parameters.AddWithValue("#dis", 1.5);
cn.Open();
exeSql.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally
{
MessageBox.Show("Query added!");
cn.Close();
this.readTableAdapter.Fill(this.qualityDataSet.Read);
}
So by the sounds of it, it seems like you don't quite understand how the DataGrid works. First of all the basic functionality of a DataGrid is to create columns and rows to display a set of data which is passed to it.
So when you are doing your select statement you select out a set of data and pass it to the DataGrid. However at this point the DataGrid isn't interacting with the query anymore, and the query isn't retrieving anymore data.
So in order to have the DataGrid be refreshed to show the new data, you have a few options, however the simplest I can think of for your case is to simply requery the data and pass in the new dataset that you retrieve. Then call one of the helper functions (I believe its .Refresh or .Update) to tell the DataGrid to reload itself with the new data it has received.

MySQL insert command using prepared statement and placeholders is not working

I built a MySql database and a C# Windows GUI form to with textbox fields and a timedate picker to populate a table named 'job' in my database.
I have read a few posts on this site about the importance of using prepared statements to prevent sql injection attacks and I tried to use this security feature in my code.
However it is not working. I am a web designer but very new to programming. I tried different code variations at the insert command still won't work. The samples I have found on this form involve using prepared statements with PHP, which is not what I am using.
I get the following error message: You have an error in your SQL syntax; check the manual or your MySQL server version for the right syntax to use near 'jobTitle, this.dateTimePickerJobLastUpdated')' at line 1
Does anyone know what I am doing wrong and how I can fix this?
This is the MySQL statement for the table.
CREATE TABLE job (
job_code VARCHAR(6) NOT NULL DEFAULT '',
job_title VARCHAR(30) NOT NULL DEFAULT '',
job_last_update DATE NOT NULL,
PRIMARY KEY (job_code)
)ENGINE=InnoDB CHARSET=utf8;
And this is my C# for the event handler that will save the data entry from the windows form to the database.
private void btnSaveJobsTable_Click(object sender, EventArgs e)
{
String myConnection = #"server=localhost; database=beautyshopdb; username=$$$$; password=$$$$$$";
MySqlConnection Connect = null;
try
{
Connect = new MySqlConnection(myConnection);
Connect.Open(); //open the connection
//This is the mysql command that we will query into the db.
//It uses Prepared statements and the Placeholder is #name.
//Using prepared statements is faster and secure.
String insertQuery = "INSERT INTO beautyshopdb(job) VALUES(#jobCode, #)jobTitle, #lastUpdated)";
MySqlCommand cmdInsertJobsToDataBase = new MySqlCommand(insertQuery, Connect);
cmdInsertJobsToDataBase.Prepare();
//we will bound a value to the placeholder
cmdInsertJobsToDataBase.Parameters.AddWithValue("#jobCode", "this.txtEnterJobCode.Text");
cmdInsertJobsToDataBase.Parameters.AddWithValue("#jobTitle", "this.txtEnterJobTitle.Text");
cmdInsertJobsToDataBase.Parameters.AddWithValue("#lastUpdated", "this.dateTimePickerJobLastUpdated");
cmdInsertJobsToDataBase.ExecuteNonQuery(); //execute the mysql command
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (Connect != null)
{
Connect.Close(); //close the connection
}
}
}
Thank you!
I'm not a C# developer, but this doesn't look right, I think you have an extra parenthesis before jobTitle:
String insertQuery = "INSERT INTO beautyshopdb(job) VALUES(#jobCode, #)jobTitle, #lastUpdated)";
Also you seem to be putting variable references inside quotes as if they are string constants. I would expect these to require no quotes.
cmdInsertJobsToDataBase.Parameters.AddWithValue("#jobCode", "this.txtEnterJobCode.Text");
Should be:
cmdInsertJobsToDataBase.Parameters.AddWithValue("#jobCode", this.txtEnterJobCode.Text);

WPF/SQL - how to get tables from a selected database into a ListView

Good evening,
i'm at the beginning of an IT apprenticeship and i've started my own little project. I've got following problem:
I've created in WPF a standard Login Window for getting SQL Connection Datas. This Window is working fine and i only can switch to the next window when the entered Login-Datas are correct. My problem is the second window. In the second one i have one ListBox for listing every Database from the connected Server. Next to this ListBox i've a ListView. In this ListView i want to see the tables from the selected Database.
Code for listing Databases:
SqlConnection GetConnection = new SqlConnection("Server=admin-pc;user Id=sa;Password=123;");
try
{
this.libDatabase.Items.Clear();
DataTable databases = new DataTable("Databases");
using (IDbConnection connection = GetConnection)
{
IDbCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM sys.Databases";
connection.Open();
databases.Load(command.ExecuteReader(CommandBehavior.CloseConnection));
}
this.libDatabase.Items.Clear();
foreach (DataRow row in databases.Rows)
this.libDatabase.Items.Add(row[0].ToString());
}
catch (SqlException)
{
this.libDatabase.Items.Clear();
this.libDatabase.Items.Add("Connection error");
}
catch (Exception ex)
{
MessageBox.Show("Error while loading available databases");
}
finally
{
GetConnection.Close();
}
libDatabase is the name of the ListBox.
This Code is working good and every Database is shown in my ListBox. But no i've a totally Blackout. How do i get the Tables from the selected Database into the ListView? I've tried the same way like i did with the Databases but with a different "SELECT"-Statement ==> "select * from {0}", listbox.SelectedItem
Here are different Codes i've tried but i think that i do something completely wrong.
First Version:
List<ListViewItem> gettables = new List<ListViewItem>();
if (libDatabase.SelectedItem != null)
{
SqlConnection con = new SqlConnection("Server=admin-pc;user Id=sa;Password=123;");
string strSQL = string.Format("select * from {0}", libDatabase.SelectedItem);
SqlCommand cmd = new SqlCommand(strSQL, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
}
reader.Close();
con.Close();
}
Second Version:
SqlConnection GetConnection = new SqlConnection("Server=admin-pc;user Id=sa;Password=123;");
try
{
this.libTables.Items.Clear();
DataTable tables = new DataTable("Tables");
using (IDbConnection connection = GetConnection)
{
IDbCommand command = connection.CreateCommand();
if (libDatabase.SelectedItem != null)
{
command.CommandText = string.Format("SELECT * FROM {0}", libDatabase.SelectedItem);
connection.Open();
tables.Load(command.ExecuteReader());
}
}
this.libTables.Items.Clear();
foreach (DataRow row in tables.Rows)
this.libTables.Items.Add(row[0].ToString());
}
catch (SqlException)
{
this.libTables.Items.Clear();
this.libTables.Items.Add("Connection error. Check server");
}
catch (Exception ex)
{
MessageBox.Show("Error while loading available tables" + ex);
}
finally
{
GetConnection.Close();
}
libTables is the name of the ListView.
Maybe i did it completely wrong or there's just one code block false.
Thank you for supporting.
Dave S.
Try this select statement instead:
command.CommandText = string.Format("SELECT * FROM {0}.sys.tables", libDatabase.SelectedItem);
As the database names are to be found in sys.databases within master, so too the tables are to be found within sys.tables for each database.
It pays to step through code of this nature with a debugger, and/or put a breakpoint at each meaningful location. Verify each sql statement built in the code is exactly what you intended, and execute each statement within Sql Management studio using the same permissions under which it is being executed within your code, to ensure the statement will produce the results you want.
Edit for triggering the table load:
You must also ensure the table-loading process is triggered by the appropriate action. In this case, it would most likely need to be triggered by the user selecting a database within the database listbox. You'll need to add an event handler for the SelectionChanged event to the listbox. (Note that I'm assuming you're not using the MVVM pattern based on the code samples you included in your question.)
Add the SelectionChanged attribute to your ListBox definition:
<ListBox Name="libDatabase" SelectionChanged="libDatabase_SelectionChanged">
And in the codebehind, define the event handler:
private void libDatabase_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if(libDatabase.SelectedItem != null)
{
// open a database connection and select your tables here.
}
}

Validate database file schema before open

I have an application that saves and opens data (which is saved as SQL CE database file). Every time the project gets saved, a new .sdf file is generated with table structure defined by my code and I do not need to run any validation against it.
My concern is when user import (open) the .sdf file in a OpenFileDialog, there will be chance user may select a database file generated from a different application (i.e. having a different table schema). I would need to validate the importing database table schema or the application may crash if the wrong database file is opened and processed.
I do not need to compare schema between files. All I need is to check if the database file contain a certain table structure or table names (which I think should be sufficient for my purpose). What is the easiest way to do this?
[EDIT]
I used the following method to validate the database file, which works. I use a string array to checked against a SqlCeDataReader (which stores the Table name). It works but I wonder if there's an even easier way - is there a build in method in .NET to use?
using (SqlCeConnection conn = new SqlCeConnection(validateConnStr))
{
using (SqlCeCommand cmd = new SqlCeCommand(#"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES", conn))
{
try
{
conn.Open();
SqlCeDataReader rdr = cmd.ExecuteReader();
string[] tableArr = { "FirstTable", "SecondTable" };
int ta = 0;
while (rdr.Read())
{
if (rdr.GetString(0) != tableArr[ta])
{
isValidDbFile = false;
}
else
{
isValidDbFile = true;
}
ta++;
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.ToString());
}
finally
{
conn.Close();
}
}
}
Open the database (make sure to have error handling for this, as the user can point to any file).
run: SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'MyTable'
If this returns data, your table is there.

Categories

Resources