Storing SQL Tables for use in visual studio - c#

I'm trying to create a windows form application that manipulates data from several tables stored on a SQL server.
What's the best way to store the data locally, while the application is running? I had a previous program that only modified one table, and that was set up to use a datagridview. However, as I don't necessarily want to view all the tables, I am looking for another way to store the data retrieved by the SELECT * FROM ... query.
Is it better to load the tables, make changes within the C# application, and then update the modified tables at the end, or simply perform all operations on the database, remotely (retrieving the tables each time they are needed)?

You can take in one table at a time using a ConnectionString and assign it to a DataTable. You can then make changes to the DataTable in any form you want. Once you are finished making the changes you can commit the changes back to Database by using a DataAdapter.
Here's how to get a table:
DataTable table;
using (SqlDbConnection connection = new SqlDbConnection(connectionString))
{
connection.Open();
using (SqlDbCommand command = new SqlDbCommand(tableName, connection))
{
command.CommandType = CommandType.TableDirect;
SqlDbDataReader dr = command.ExecuteReader(CommandBehavior.CloseConnection);
table = new DataTable(tableName);
routeID.Load(dr);
}
}
Here's how to commit the table after changes, make sure to assign your DataTable to a DataSet in order to get the changes for commit:
DataSet dataSet = new DataSet();
dataSet.add(table);
using (var adapter = new SqlDbDataAdapter("SELECT * FROM " + tableName, connection))
{
using (var builder = new SqlDbCommandBuilder(adapter))
{
adapter.Fill(dataSet, tableName);
using (DataSet newSet = dataSet.GetChanges(DataRowState.Added))
{
builder.QuotePrefix = "[";
builder.QuoteSuffix = "]";
adapter.InsertCommand = builder.GetInsertCommand();
adapter.Update(newSet, tableName);
}
}
}
There may be a few miss Types, I didn't compile to check for Errors. Good Luck.

The DataSet object has methods that give you the ability to manipulate data from multiple tables in memory, and then save those changes back to the database. Whether that's a good idea depends on your requirements and data--are there multiple simultaneous users, how do you need to handle conflicting updates, etc. I usually prefer to write changes back to the DB immediately, but then, I usually work in a web app context.

Related

How to altertable if not exist in c#?

I have an API in .NET Core 3.1 which insert some data to my databases, the issue is that i had to add a new column to the column where i'm inserting the data, as then the api is called i'm dynamically connect to the database to which i should do the insert, how could i make an altertable if that column not exist and then insert the new item?
Here is the method where i'm inserting the stuff:
public static IActionResult InsertOrder(string piva, string idNegozio, RiepilogoTakeaway ordine, HttpResponse Response) {
string connectionString = getConnectionString(piva);
var query_ordine = #"INSERT INTO `ordini` (`TIPO_OR`, `TAVOLO_OR`, `ORA_OR`, `SENT_OR`, `ID_OR_CFG`, `LOTTERIA_OR`) VALUES (#tipo, #tavolo, NOW(), 0, #id, #lotteria); SELECT LAST_INSERT_ID();";
using var connection = new MySqlConnection(connectionString);
using var cmd = new MySqlCommand(query_ordine, connection);
cmd.Parameters.AddWithValue("#tipo", "STB");
cmd.Parameters.AddWithValue("#tavolo", 0);
cmd.Parameters.AddWithValue("#id", idNegozio);
cmd.Parameters.AddWithValue("#lotteria", ordine.lotteria);
connection.Open();
cmd.Prepare();
string idOrdine = cmd.ExecuteScalar().ToString();
...
}
And that's the alter table i should execute:
ALTER TABLE `ordini`
ADD COLUMN `LOTTERIA_OT` VARCHAR(10) NULL AFTER `ID_OR_CFG`;
Which would be the best way to do it?
Try to deploy the SQL changes before calling it. It's very likely that you'll need higher level of privilege in the database to run the alter or add column, for example, if the SQL user you are using to insert the order doesn't have permissions to change the DB schema.
However, if that is still an option, you will need to execute the SQL schema changeusing command.ExecuteNonQuery().
Possibly worth creating a new method "PrepareSqlTable" so you can call before your query runs. Bear in mind that will impact your application performance/scalability because now we'll be checking that on every single query.
Another alternative, handle this in the catch by looking into the error message and creating it accordingly (provides more performance benefits than the previous option).

How to copy a populated MYSQL-Table to another Database in C#

I am using C#, .net 3.5 and a MySQL-Database. I have a populated table on Server 1 which I want to copy to Server 2. On Server 2 I have the same table structure, but the table is empty. Now I want to copy the data from Server 1 to Server 2.
I connect to Server 1 and fill the information into a DataSet - no problem. Then I open a second connection to the other server. My problem is, how can I store this DataSet on the second Server? The Update()-command has no effect, even if I set the same UpdateCommand und InsertCommand-CommandText as for Server 1. I get no error when I use Update(DataSet,"TableName"), but the table is still empty.
For MSSQL-Databases BulkCopy would be an option, but it seems that there is no equivalent for MySQL DBs!?
I do not want to use mysqldump, I want to do it programmaticaly in C# on a client.
Any idea?
EDIT:
MySqlConnection conn_DB1 = new MySqlConnection(connString_DB1);
MySqlDataAdapter adp_DB1 = new MySqlDataAdapter("select * from myDB", conn_DB1);
DataSet theDataSet_DB1 = new DataSet();
adp_DB1.Fill(theDataSet_DB1, "myDB"); //everything is fine, the Data is there
MySqlConnection conn_DB2 = new MySqlConnection(connString_DB2);
MySqlDataAdapter adp_DB2 = new MySqlDataAdapter("select * from myDB", conn_DB2);
DataSet theDataSet_DB2 = new DataSet();
adp_DB1.Fill(theDataSet_DB2, "myDB"); //this DataSet is empty, of course
theDataSet_DB2 = theDataSet_DB2.Copy(); //the data is updated, the second DataSet has all the rows as expected
adp_DB2.Update(theDataSet_DB2, "myDB"); //no error on execution, but the table is still empty on the second server
The rows in theDataSet_DB2.Tables are "unchanged", so any occurs. You must mark rows as "added" before to update them.
foreach (DataTable table in theDataSet_DB2.Tables)
foreach (DataRow row in table.Rows)
row.SetAdded ();
It's necessary to build a MySqlCommandBuilder associated to the dataAdapter:
new MySqlCommandBuilder (dataAdapter);
I am not sure which library you use to access MySQL DB...
For a "pure ADO.NET" with the original ADO.NET provider from MySQL see this artcile http://www.codeproject.com/KB/database/GenericCopyTableDataFcn.aspx
IF you use the MySQL .NET connector there is a class called MySqlBulkLoader see http://dev.mysql.com/doc/refman/5.1/en/connector-net-programming-bulk-loader.html . this class takes AFAIK a file - so would have to create a file from the source table first to use it...
IF you are using the Devart MySQL components you could:
MySqlLoader ML = new MySqlLoader("myDB", conn_DB2);
ML.CreateColumns();
ML.LoadTable(theDataSet_DB1.Tables[0]);

Tutorial on connecting c# to SQL server

I want to be able to edit a table in a SQL server database using c#.
Can someone please show me a very simple tutorial on connecting to the DB and editing data in a table.
Thank you so much.
First step is to create a connection. connection needs a connection string. you can create your connection strings with a SqlConnectionStringBuilder.
SqlConnectionStringBuilder connBuilder = new SqlConnectionStringBuilder();
connBuilder.InitialCatalog = "DatabaseName";
connBuilder.DataSource = "ServerName";
connBuilder.IntegratedSecurity = true;
Then use that connection string to create your connection like so:
SqlConnection conn = new SqlConnection(connBuilder.ToString());
//Use adapter to have all commands in one object and much more functionalities
SqlDataAdapter adapter = new SqlDataAdapter("Select ID, Name, Address from myTable", conn);
adapter.InsertCommand.CommandText = "Insert into myTable (ID, Name, Address) values(1,'TJ', 'Iran')";
adapter.DeleteCommand.CommandText = "Delete From myTable Where (ID = 1)";
adapter.UpdateCommand.CommandText = "Update myTable Set Name = 'Dr TJ' Where (ID = 1)";
//DataSets are like arrays of tables
//fill your data in one of its tables
DataSet ds = new DataSet();
adapter.Fill(ds, "myTable"); //executes Select command and fill the result into tbl variable
//use binding source to bind your controls to the dataset
BindingSource myTableBindingSource = new BindingSource();
myTableBindingSource.DataSource = ds;
Then, so simple you can use AddNew() method in the binding source to Add new record and then save it with update method of your adapter:
adapter.Update(ds, "myTable");
Use this command to delete a record:
myTableBindingSource.RemoveCurrent();
adapter.Update(ds, "myTable");
The best way is to add a DataSet from Project->Add New Item menu and follow the wizard...
Assuming you're using Visual Studio as your IDE you could just use LINQ to SQL. It's a pretty simple way to interact with your database and it should be pretty quick to get going.
Using LINQ to SQL is a pretty simple walk through in getting it up and running.
Have a read of the MSDN tutorial on Creating Data Applications. You may be able to clarify your question, or find the answers you need.
There is info on editing the data in the app but you have to get connected and load it into your app first.
The only reason to do this in C# is if you want to automate it somehow or create an interface for non-technical users to interact with the database. You can use a GridView control with an SQL datasource to manipulate the data.
#kevin: if he's just learning, I think its probably simpler to have him use SQLCommand object (or SQLDataAdapter).

C# Sync MS Access database to sql server

I am trying to set up a synchronization routine in C# to send data from a ms access database to a sql server. MS Access is not my choice it's just the way it is.
I am able to query the MS Access database and get OleDbDataReader record set. I could potentially read each individual record and insert it onto SQL Server but it seems so wasteful.
Is there a better way to do this. I know I could do it in MS Access linking to sql server and perform the update easy but this is for end users and I don't want them messing with access.
EDIT:
Just looking at SqlBulkCopy I think that may be the answer if I get my results into DataRow[]
I found a solution in .NET that I am very happy with. It allows me to give the access to the sync routine to any user within my program. It involves the SQLBulkCopy class.
private static void BulkCopyAccessToSQLServer
(CommandType commandType, string sql, string destinationTable)
{
using (DataTable dt = new DataTable())
{
using (OleDbConnection conn = new OleDbConnection(Settings.Default.CurriculumConnectionString))
using (OleDbCommand cmd = new OleDbCommand(sql, conn))
using (OleDbDataAdapter adapter = new OleDbDataAdapter(cmd))
{
cmd.CommandType = commandType;
cmd.Connection.Open();
adapter.SelectCommand.CommandTimeout = 240;
adapter.Fill(dt);
adapter.Dispose();
}
using (SqlConnection conn2 = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString))
{
conn2.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(conn2))
{
copy.DestinationTableName = destinationTable;
copy.BatchSize = 1000;
copy.BulkCopyTimeout = 240;
copy.WriteToServer(dt);
copy.NotifyAfter = 1000;
}
}
}
}
Basically this puts the data from MS Access into a DataTable it then uses the second connection conn2 and the SqlBulkCopy class to send the data from this DataTable to the SQL Server. It's probably not the best code but should give anyone reading this the idea.
You should harness the power of SET based queries over RBAR efforts.
Look into a SSIS solution to synchronize the data and then schedule the package to run at regular intervals using SQL Server Agent.
You can call an SSIS package from the command line so you can effectively do it from MS Access or from C#.
Also, the SQL Server, the MS Access DB and the SSIS package do not have to be on the same machine. As long as your calling program can see the SSIS package, and the package can connect to the SQL Server and the MS Access DB, you can transfer data from one place to another.
It sounds like what you are doing is ETL. There are several tools that are built to do this and to me, there is little reason to reinvent the functionality. You have SQL Server, therefore you have SSIS. It has a ton of tools for automated transformations, cleanups, lookups, etc. that you can use out of the box.
Unless this is a real cut-and-dry data load and there is absolutely no scope for the complexity of the upload to increase later on (yeah, right!) I would go with a tried and tested ETL tool.
If SQL Server Integration Services isn't an option, you could write out to a temporary text file the data that you read from Access and then call bcp.exe to load it to the database.
I have done something like this before.
I used
OleDbConnection aConnection = new OleDbConnection(String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", fileName));
aConnection.Open();
to open the access db. Then
OleDbCommand aCommand = new OleDbCommand(String.Format("select * from {0}", accessTable), aConnection);
OleDbDataReader aReader = aCommand.ExecuteReader();
to execute the read from the table. Then
int fieldCount = aReader.FieldCount;
to get the field count
while (aReader.Read())
to loop the records and
object[] values = new object[fieldCount];
aReader.GetValues(values);
to retrieve the values.
There are several ways to sync but it can give a problem when you change a field name in sql server or add a new column or delete. The best option would be:
Create connections for sql server and oledb.
Write custom query to fetch record from one connection and save it to another.
Before executing make sure to program in a way that you update all table definitions.
In my case this helped in a way because the load on sql server became down.
can you not transfer Access file to the server and delete it once sync is complete?
You can create windows service for that..

Getting a DataSet from an SQL Express Server C#

How can I get a DataSet with all the data from a SQL Express server using C#?
Thanks
edit: To clarify, I do want all the data from every table. The reason for this, is that it is a relatively small database. Previously I'd been storing all three tables in an XML file using DataSet's abilities. However, I want to migrate it to a database.
You can use the GetSchema method to get all the tables in the database and then use a data adapter to fill a dataset. Something like this (I don't know if it compiles, I just paste some code and change it a bit):
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.SqlClient");
DataTable tables = null;
DataSet database = new DataSet();
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = "Data Source=(local);Initial Catalog=Northwind;Integrated Security=True";
string[] restrictions = new string[4];
// Catalog
restrictions[0] = "Northwind";
// Owner
restrictions[1] = "dbo";
// Table - We want all, so null
restrictions[2] = null;
// Table Type - Only tables and not views
restrictions[3] = "BASE TABLE";
connection.Open();
// Here is my list of tables
tables = connection.GetSchema("Tables", restrictions);
// fill the dataset with the table data
foreach (DataRow table in tables.Rows)
{
string tableName = table["TABLE_NAME"].ToString();
DbDataAdapter adapter = factory.CreateDataAdapter();
DbCommand command = factory.CreateCommand();
command.Connection = connection;
command.CommandType = CommandType.Text;
command.CommandText = "select * from [" + tableName + "]";
adapter.SelectCommand = command;
adapter.Fill(database, tableName);
}
}
EDIT:
Now I refactored it a bit and now it's working as it should. The use of DbConnection and DbProviderFactories is for database engine abstraction, I recommend using it so you can change the database engine changing this line and the connection string:
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OracleClient");
The GetSchema method will retrive all tables from your database to a DataTable and then we get all the data from each table to the DataSet using the DataAdapter.
I think you need to narrow down the question somewhat... All the data? You mean, all the data in every table in every database? Well, the only answer to that is, a lot of code.
To connect to and talk to a SQL Server Express database engine, use the classes in the System.Data.SqlClient namespace, namely:
SqlConnection: Connect to the database
SqlCommand: Talk to the database
SqlDataReader: Iterate over data retrieved from the database
You can check the MSDN pages for all of these classes by clicking on the links above.
Here are some overview-links with more information:
CodeProject: Beginners guide to accessing SQL Server through C#
DevHood: Accessing SQL Server Data in C# with ADO.NET
Note that by and large, you use a SQL Server Express database engine the same way as the full SQL Server product, the difference is more in the tools you get with it, and some limitations in the express engine. Other than that you can just use the classes and language that you would use for a normal SQL Server database engine installation.
If this post didn't answer your question, please elaborate, and you have a higher chance of getting the answer you seek.
This can be done by using dataAdapter class.

Categories

Resources