I'm coming over from PHP and am having a hard time with storing information into my newly created local database. I'm using Microsoft Visual C# 2010 to help me learn and develop.
I'm reading that many people do not like datasets and would opt to ignore them all together. That is fine if I am able to hard-wire into my local database. (I did not use the server database option provided because I'll turn my completed product into a commercial solution and this will require the users to store their information into a local database that stores their project data.
I've made a video showing my windows form and my database, and the extent of my knowledge so far. Maybe you guys can help? http://screencast.com/t/x9Qt1NtOgo6X
There are many ways to access a database from your application. These range from low-level ado.net commands (SqlDataReader, etc..) to using an Object Relational Mapper (ORM) such as Entity Framework.
All of them will require that you learn the technologies, but you can start here:
http://windowsclient.net/learn/videos.aspx
Here's some code that uses SQLServer to do a direct insert, although you'll need a connection string to your database.
Include the SQL server database includes.
using System.Data.SqlClient;
using System.Data.SqlTypes;
.
.
.
using (SqlConnection cn = new SqlConnection("XXXXX")) // must put a connection string to your database here
{
cn.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO Session(field1, field2) VALUES(#Value1, #Value2)"))
{
cmd.Parameters.AddWithValue("#Value1", 4);
cmd.Parameters.AddWithValue("#Value2", "test");
cmd.ExecuteNonQuery();
}
}
Well, if you want a quick, almost close to the wire code like the way you used to have with PHP, the following code should work.
var conn = new SqlConnection("Your Connection String");
var command = conn.CreateCommand();
command.CommandText = "insert into sessions (id, name) values (#id, #name)";
command.Parameters.AddWithValue("#id", "");
command.Parameters.AddWithValue("#name", "test");
conn.Open();
command.ExecuteNonQuery();
command.Dispose();
conn.Close();
In the long run, it would be better if you get accustomed to one of the data-related / ORM frameworks such as Entity Framework, NHibernate and the likes. That would really help a lot in data manipulation and make your life a whole lot easier.
It depends on your requirments, but for most situations, I would highly recommend you use Entity Framework or Linq to Sql data classes. You'd be much better off... go with the latter as a start... hope it helps.
[Edited]
If you want to see how easy an ORM can be:
right-click on your project
select Add New Item
Choose Linq to Sql Data Classes
When you've added it, you'll have a blank .dbml file
Go to server explorer and add a connection to the sql db
Drag and drop the tables wherever you like
Start using the entities like this:
using (DataClasses1DataContext db = new DataClasses1DataContext("Data Source=localhost\sqlexpress; Initial Catalog=myDBName; Integrated Security=true"))
{
IEnumerable citiesForUSA = db.Cities.Where(x => x.Country.Name == "United States");
City city = new City();
city.Name = "Metropolis";
//etc
db.Cities.InsertOnSubmit(city);
db.SubmitChanges(); // <-- INSERT INTO completed
//etc
}
Good luck!
:-)
Related
This question already has answers here:
Using Prepared Statement in C# with Mysql
(2 answers)
Closed 12 months ago.
I am getting this error message:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near ''D:\AirMaintStorage\' where id=1' at line 1
I run this in WorkBench and it works correctly but from my code in my app I get the error above. Here is my code:
string SQL = "Update Company_Table set Company_Table_Default_Storage='";
SQL += ra.EscFunction(DefaultStorage);
SQL += "' where id=";
SQL += cp.id.ToString();
MySql.Data.MySqlClient.MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection (ra.conn_String1);
MySql.Data.MySqlClient.MySqlCommand cmd = new MySql.Data.MySqlClient.MySqlCommand(SQL, conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
The query is:
Update Company_Table set Company_Table_Default_Storage='D:\\AirMaintStorage\\' where id=1
ra is a utilities class that holds the connection information and escfunction escapes apostrophes in a string. cmp.cp.id is the id field of my company table.
I expect there's a bug in EscFunction(). You should remove that function from your code base completely; it's entirely the wrong way to approach the issue. It is not correct to sanitize your database inputs!
Rather, the only correct approach is to QUARANTINE your database inputs using parameterized queries, as demonstrated below:
string SQL = "
UPDATE Company_Table
SET Company_Table_Default_Storage= #DefaultStorage
WHERE ID= #ID";
using (var conn = new MySqlConnection(ra.conn_String1))
using (var cmd = new MySqlCommand(SQL, conn))
{
cmd.Parameters.AddWithValue("#DefaultStorage", DefaultStorage);
cmd.Parameters.AddWithValue("#ID", cp.id);
conn.Open();
cmd.ExecuteNonQuery();
} // No need to even call conn.Close(); The using block takes care of it.
This is different than "sanitizing", because the quarantined values are never merged back into the SQL command text, even on the server.
Also note the use of using blocks to manage the connection lifetime.
Finally, I want to address this comment:
I have been trying to move to a more multi-platform environment so I have started moving my app to MySQL.
I'm getting outside the realms of the both the question scope and the fact-based verifiable-answers we like to write for Stack Exchange here, and more into an expression of my personal opinion on a specific technology. Nevertheless, I didn't want to leave that comment alone.
I do get wanting to support a broader set of database or hosting technologies, but you should know the MySql product spent many years (from ~2005 to ~2018) almost completely stagnant. It has fallen significantly behind other options and is the least standards compliant of the major products in the space. The good news is it seems to be progressing again, but right now if I needed to move an app to a new open source DB today I'd pick Postgresql instead, and it wouldn't be a close decision.
Of course, your use case may be different, but I think MySql has a reputation as the default option that no longer reflects that actual state of the technologies, and hasn't for some time now. At the same time, SQL Server is now perfectly happy to run in linux, meaning it's not required to switch to MySql or anything else in order to enable multiplatform hosting.
C#
I am currently working on a project that relies on downloading a table roughly 100 entries.
I first download the table and store it in a local variable, then link the variable to a DataGridView where the user can edit values.
Once done the user pushes save and it must update the table in the SQL DB with the changed information.
I am asking for a best practice here, is it advisable to delete the rows you have changed and bulk upload the changes or update based or even multiple parameters?
I know when working with SQL exclusively, you can use commands like UPDATE FROM and use tables as the source but I do not know how this would work using C#.
Thanks for help in advance.
public DataTable GetSingleTable(string sTableName, string sGetConnString)
{
DataTable dtTabletoReturn = new DataTable();
string sCommand = "SELECT * FROM " + sTableName+ " WHERE
BranchID = '"+ sBranchID +"'";
SqlConnection sqlConnection = new SqlConnection(sGetConnString);
sqlConnection.Open();
SqlDataAdapter sqlOilAdapter = new SqlDataAdapter(sCommand, sqlConnection);
sqlOilAdapter.Fill(dtTabletoReturn);
sqlConnection.Close();
return dtTabletoReturn;
}
Entity Framework MVC will be the best practice for you. You can start with the basics from here:
https://www.entityframeworktutorial.net/what-is-entityframework.aspx
As others have mentioned, if this is not impossible in Your project, try EF core or Dapper - both should simplify your struggles (not without adding some other later in some peculiar scenarios).
If going with EF core, take a look at connected / disconnected scenarios.
In any case, when getting data by using EF in, lets say for simplicity, connected scenario, the EF core context tracks entities (Your data).
It will detect changes made to those entities, so in the end, just calling a SaveChanges() method on EF core DbContext will save and transfer just the modified data.
Mind that this very basic explanation, You will have to read about it by Yourself if You choose to go that way.
So after fiddling around and I rate the best procedure would be to use the DataAdapter Update command, I was looking for best practices here. Unfortunately the Entity Framework, as far as I can tell, works best when building an application from scratch. https://www.youtube.com/watch?v=Y-aGjF6_Ptc&t=166s <- this was the best so far.
Consider a block of code like this:
using (SqlConnection c = new SqlConnection("{connection string}"))
{
c.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO Table (Field1, Field2) VALUES (#Field1, #Field2)", c))
{
cmd.Parameters.AddWithValue("#Field1", "some value");
cmd.Parameters.AddWithValue("#Field2", 10);
cmd.ExecuteNonQuery();
}
}
I would like to be able to see the actual statement sent to the server, but the kicker is I don't have access to SQL Server Profiler via our Network/SQL administrators. Is there any way I can get at the actual statement submitted to the server?
There are a range of tools that do exactly this. If you are in asp.net, you may find MiniProfiler a good start (you can use it on other platforms, but the UI tooling is stronger on asp.net). The main change involved here would be to move from SqlCommand etc to use c.CreateCommand, since it works by wrapping the connection (decorator pattern) - while it is still a DbConnection, the outermost object is not a SqlConnecion any more. I have to say, though - in this particular example you already know the exact command sent to the server. It is useful for finding the surprises, though. If that doesn't suit, "Hibernating Rhinos" offer a range of profiling tools, and many Orpheus general-purpose profiling tools will include ado.net tools; the main reason I mention MiniProfiler is that is is free, readily available, and very low impact (it is what we wrote to profile stackoverflow.com - and we leave it "on" 24x7)
I am debugging code someone else wrote that calls a lot of stored procedures (sql server 2008 r2) from C# code. The C# code looks like this
SqlCommand sqlCommand = new SqlCommand(strSP, ConnectionOpen());
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.CommandTimeout = intTimeOut;
//System.Data.SqlClient.SqlParameter[] prmSQL
if (prmSQL != null)
{
while (i < prmSQL.Length)
{
sqlCommand.Parameters.Add(prmSQL[i]);
i = i + 1;
}
}
SqlDataReader sqlReader = sqlCommand.ExecuteReader();
For debugging my stored procedures I really need the string that sql management studio needs which is like
exec sp_name param one, param two (with quotes if needed for strings and dates..)
The sql command object does not provide this string via some property. The only way I know is to run the sql profiler on sql server and grab the string. Unfortunately the DBA's do not like this since they say running the profiler impacts performance. Is there any addin or code snippet you guys use to get the sp exec string from c# code ? Whats the best way to get this string ? Thanks
You could use a tool like mvc-mini-profiler available on NuGet (note: the name is misleading; it isn't limited to MVC). Minor clarification - since it wraps the connection, you would need to use the abstract DbConnection rather than SqlConnection, and then you just tweak the one line of code (probably in a utility class somewhere) that creates your connection, i.e. instead of:
var conn = new SqlConnection(someString);
return conn;
you might use:
var conn = new SqlConnection(someString);
return new StackExchange.Profiling.Data.ProfiledDbConnection(
conn, MiniProfiler.Current);
There's a couple of other steps to enable it (all shown on the site page), but it literally takes 2 minutes to add to an MVC application. The output is that it monitors, in real time, for enabled users (developers etc), all the activity. We use it 24x7 on stackoverflow/stackexchange (meaning: we made very sure it didn't impact performance). A live demo is available on https://data.stackexchange.com/ - just log in, and the profiling data is visible top-left. It automatically presents the data in a form runnable from SSMS, because that is how we often use it - so: it presents parameters as though they were variable declarations / initializations.
It also plays nicely with ORMs such as LINQ-to-SQL and dapper-dot-net (and many others).
Rep is too low (still a noob to StackOverflow)to comment so I'm posting this as an answer. My apologies. However, you might consider looking at SMO. SMO is a .NET object model that can be used to interact with SQL Server. Using SMO you can get a reference to a specific Stored Procedure
and then enumerate it's parameters.
That might help you get started.
In order to construct the EXEC command, you will need to know the parameter names used by the procedure. I believe you can find them by using the GetDbSchemaTable method, whcih will retrieve stored procedure SQL (I have done this using MS-Access/OLEDB and am assuming it works the same for MS-SQL/SqlClient):
using (conn == new OleDb.OleDbConnection(DBConnection)) {
conn.Open();
DataTable DBObject = conn.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Procedures, null);
}
The column named "PROCEDURE_DEFINITION" contains the procedure's SQL and hopefully the parameter list.
You may also want to have a look at Obtaining Schema Information from a Database.
HTH
We document our SQL Server database by creating table and column level Description extended properties. We usually enter these via SSMS.
My question is this. I'm creating a C# application where I'd like to read the extended properties for a particular table and its associated columns.
Can someone show me how I might go about doing this?
Thanks - Randy
You simply ask for them using the built-in fn_listextendedproperty. The result of this function is an ordinary table result set that you read in C# using your data access tool of choice (SqlCommand/SqlDataReader, linq, datasets etc).
Read this: Extract SQL Column Extended Properties From LINQ in C# and see if that's something you could do in your situation.
A full example for a simple property:
In SQL Server :
Code:
String strVersion;
string cmd = "SELECT value from sys.extended_properties where name = 'MinimumClientVersion'";
using (var connection = new SqlConnection(connectionString))
using (var comm = new SqlCommand(cmd, connection))
{
connection.Open();
strVersion = (string)comm.ExecuteScalar();
connection.Close();
}
Version MinimumVersion = new Version(strVersion);