I am writing a console program in C# and I need to use a database.
I am looking for very basic tutorials on connecting with and using a db from a C# console program. I haven't been able to find anything basic enough yet and I hope people here can help me find the info I need. I've read the material on MSDN, but MSDN assumes basic knowledge about these things that I am still looking for.
I have created a db within VS Express in my project, created tables, and written some starter records into the tables. I'm trying to find out exactly what each of these things is, and how to determine how to apply them in my project:
SQLConnection
SQLConnection class
SQLCommand
SQLDataAdapter
DataSets
Thanks.
Something like:
using System.Data;
using System.Data.SqlClient;
using(SqlConnection connection = new SqlConnection("")){
SqlCommand command = new SqlCommand(#"
insert into
tblFoo (
col1,
col2
) values (
#val1,
#val2
)",
connection
);
SqlParameter param = new SqlParameter("#val1", SqlDbType.NVarChar);
param.Value = "hello";
command.Parameters.Add(param);
param = new SqlParameter("#val2", SqlDbType.NVarChar);
param.Value = "there";
command.Parameters.Add(param);
command.ExecuteNonQuery();
connection.Close();
}
-- Edit:
Though, of course, when you start doing serious things, I recommend an ORM. I use LLBLGen (it costs money, but most definitely worth it).
-- Edit:
SqlConnection
The thing through which you communicate to the database. This will hold the name of the
server, the username, password, and other misc things.
SqlCommand
Something that holds the sql statement you want to send to the server. This may be an 'update' or 'insert' or 'select' or anything. Depending on what it is, you use a different method to execute it, to possible get data back.
SqlDataAdapter
A strange one; it's used specifically to fill a 'DataSet'. It basically does a bit of work for you, adding the information it finds to the set.
DataSet
Not sure how simple you want this. It's just a collection of returned data, in a table-like format, that you can iterate over. It contains DataTables, because some queries can return more than one table. Typically, though, you'll only have one table, and you can bind to it, or whatever.
Create a sqlconnection, Open it, Create a sqlcommand, execute it to get a sqldatareader, voila. You won't need a dataadapter for a simple example.
string connectionString = "...";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
string sql = "select field from mytable";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr[0]);
}
}
There's a tutorial on ADO.NET that covers a lot of the things you're looking for at http://www.csharp-station.com/Tutorials/AdoDotNet/Lesson01.aspx. Lesson 1 is mostly background but lesson 2 and onwards goes over SQL client objects.
Another tutorial at http://www.codeproject.com/KB/database/sql_in_csharp.aspx covers some of the basics (SqlConnection, SqlCommand).
I bought a book called Pragmatic ADO.NET.
Well, there are two ways to interact with a SQL Server database in C#. The first is with LINQ, and the second is with the SqlClient library.
LINQ
Ever since .NET 3.0, we've had access to LINQ, which is a pretty impressive ORM and way to deal with collections and lists. There are two different ways that LINQ can work with a database. They are:
LINQ to SQL
LINQ to Entities
Scott Gu has a pretty good tutorial on LINQ to SQL, as well. I'd recommend LINQ to SQL for just getting started, and you can use a lot of that in LINQ to Entities going forward.
A sample select to grab all customers in New York would be:
var Custs = from c in Customers
where c.State = 'NY'
select c;
foreach(var Cust in Custs)
{
Console.WriteLine(Cust.Name);
}
SqlClient
The traditional C# way to hit a SQL Server database (pre-.NET 3.0) has been via the SqlClient library. Essentially, you create a SqlConnection to open up a connection to the database. If you need help with your connection strings, check out ConnectionStrings.com.
After you've connected to your database, you will use the SqlCommand object to interact with it. The most important property for this object is the CommandText. This accepts SQL as its language, and will run raw SQL statements against the database.
If you're doing an insert/update/delete, you will use the ExecuteNonQuery method of SqlCommand. However, if you're doing a select, you will use ExecuteReader and return a SqlDataReader. You can then iterate through the SqlDataReader to get your results.
The following is the code to grab all customers in New York, again:
using System.Data;
using System.Data.SqlClient;
//...
SqlConnection dbConn = new
SqlConnection("Data Source=localhost;Initial Catalog=MyDB;Integrated Security=SSPI");
SqlCommand dbComm = new SqlCommand();
SqlDataReader dbRead;
dbConn.Open();
dbComm.Connection = dbConn;
dbComm.CommandText = "select name from customers where state = #state";
dbComm.Parameters.Add("#state", System.Data.SqlDbType.VarChar);
dbComm.Parameters["#state"].Value = "NY";
dbRead = dbComm.ExecuteReader();
if(dbRead.HasRows)
{
while(dbRead.Read())
{
Console.WriteLine(dbRead[0].ToString());
}
}
dbRead.Close();
dbConn.Close();
Hopefully this gives you a good intro to what each approach does and how to learn more.
In general, I recommend using the Microsoft Enterprise Library for DB access. I've used it in a few projects, and am very fond of it.
See the Data Access Quickstart provided by Microsoft that should help you get started
Also, I've also grown accustomed to writing Extension Methods for extracting data from DataRows. For example, I can do something like this:
//Create an extension method, Value,
//to extract a certain type from a DataRow,
//supplying a default value to be used if DbNull.Value is encountered
DateTime someDateValue = dr["SomeDatabaseField"].Value(new DateTime());
Hope this helps!
See ADO.NET Sample Application
Examples cover
SqlClient
using System;
using System.Data;
using System.Data.SqlClient;
class Sample
{
public static void Main()
{
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");
SqlCommand catCMD = nwindConn.CreateCommand();
catCMD.CommandText = "SELECT CategoryID, CategoryName FROM Categories";
nwindConn.Open();
SqlDataReader myReader = catCMD.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));
}
myReader.Close();
nwindConn.Close();
}
}
OleDb
using System;
using System.Data;
using System.Data.OleDb;
class Sample
{
public static void Main()
{
OleDbConnection nwindConn = new OleDbConnection("Provider=SQLOLEDB;Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");
OleDbCommand catCMD = nwindConn.CreateCommand();
catCMD.CommandText = "SELECT CategoryID, CategoryName FROM Categories";
nwindConn.Open();
OleDbDataReader myReader = catCMD.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));
}
myReader.Close();
nwindConn.Close();
}
}
Odbc
using System;
using System.Data;
using System.Data.Odbc;
class Sample
{
public static void Main()
{
OdbcConnection nwindConn = new OdbcConnection("Driver={SQL Server};Server=localhost;" +
"Trusted_Connection=yes;Database=northwind");
OdbcCommand catCMD = new OdbcCommand("SELECT CategoryID, CategoryName FROM Categories", nwindConn);
nwindConn.Open();
OdbcDataReader myReader = catCMD.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));
}
myReader.Close();
nwindConn.Close();
}
}
Related
How would I delete a row from a sql database, either with stored procedures or without, right now I have tried without, using a button press.
This is what I have so far, _memberid has been sent over from a differnt form from the database(For context).
private void btnDelete_Click(object sender, EventArgs e)
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = Lib.SqlConnection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Delete * From Members where MemberId = " + _memberId;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.DeleteCommand = cmd;
adapter.Fill(MembersDataTable); // Im fairly sure this is incorrect but i used it from old code
DialogResult = DialogResult.OK;
}
If you're trying to do a simple ADO.Net-based delete, then it would be somehting like his:
private void DeleteById(int memberId)
{
// or pull the connString from config somewhere
const string connectionString = "[your connection string]";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = new SqlCommand("DELETE FROM Members WHERE MemberId = #memberId", connection))
{
command.Parameters.AddWithValue("#memberId", memberId);
command.ExecuteNonQuery();
}
}
Use parameter to prevent SQL injection.
There are essentially three main things I'm seeing...
One
You don't need the * in the query. DELETE affects the whole row, so there's no need to specify columns. So just something like:
DELETE FROM SomeTable WHERE SomeColumn = 123
Two
There's no need for a SqlDataAdapter here, all you need to do is execute the query. For example:
cmd.ExecuteNonQuery();
The "non query" is basically a SQL command which doesn't query data for results. Inserts, updates, and deletes are generally "non queries" in this context. What it would return is simply the number of rows affected, which you can use to double-check that it matches what you expect if necessary.
Three
Don't do this:
cmd.CommandText = "Delete From Members where MemberId = " + _memberId;
This kind of string concatenation leads to SQL injection. While it looks intuitively like you're using _memberId as a query value, technically you're using it as executable code. It's less likely (though not impossible) to be a problem for numeric values, but it's a huge problem for string values because it means the user can send you any string and you'll execute it as code.
Instead, use query parameters. For example, you might do something like this:
cmd.CommandText = "Delete From Members where MemberId = #memberId";
cmd.Parameters.Add("#memberId", SqlDbType.Int);
cmd.Parameters["#memberId"].Value = _memberId;
This tells the database engine itself that the value is a value and not part of the executing query, and the database engine knows how to safely handle values.
You could use a DataAdapter, but since you aren't using a datatable, it's just easier to do it without like this:
var sql = "DELETE FROM Members WHERE MemberId=#MemberId";
using(var cmd = new SqlCommand(sql, Lib.SqlConnection))
{
cmd.Connection.Open();
cmd.Parameters.Add("#MemberId",SqlDbType.Int).Value = _memberId;
cmd.ExecuteNonQuery();
}
And if you are using Dapper, you can do this:
Lib.SqlConnection.Execute("DELETE FROM Members WHERE MemberId=#MemberId", new {MemberId=_memberId});
If you are still using DataTables, I would highly recommend you look into using this (or something like this) to simplify your database accesses. It'll make CRUD logic on a database a breeze, and your code will me a lot more maintainable because you can get rid of all the odd needs to do casting, boxing/unboxing, and reduce the chances of runtime bugs because of the use of magic strings that happens so often with DataTables (column names). Once you start working with POCO classes, you'll hate having to use DataTables. That said, there are a few places where DataTables are a better solution (unknown data structures, etc), but those are usually pretty rare.
I am writing a simple reporting tool that will need to move data from a table in one Access database to a table in another Access database (the table structure is identical). However, I am new to C# and am finding it hard to come up with a reliable solution.
Any pointers would be greatly appreciated.
Access SQL supports using an IN clause to specify that a table resides in a different database. The following C# code SELECTs rows from a table named [YourTable] in Database1.accdb and INSERTs them into an existing table named [YourTable] (with the identical structure) in Database2.accdb:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
namespace oleDbTest
{
class Program
{
static void Main(string[] args)
{
string myConnectionString;
myConnectionString =
#"Provider=Microsoft.ACE.OLEDB.12.0;" +
#"Data Source=C:\Users\Public\Database1.accdb;";
using (var con = new OleDbConnection())
{
con.ConnectionString = myConnectionString;
con.Open();
using (var cmd = new OleDbCommand())
{
cmd.Connection = con;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText =
#"INSERT INTO YourTable IN 'C:\Users\Public\Database2.accdb' " +
#"SELECT * FROM YourTable WHERE ID < 103";
cmd.ExecuteNonQuery();
}
con.Close();
}
Console.WriteLine("Done.");
}
}
}
Many ways.
0) If it's only once, copy and paste the table.
1) If you want to do this inside Access, the easiest way is to create a linked table in the new database, and then a make table query in the new database.
2) You can reference the second table directly.
SELECT *
FROM TableInDbX IN 'C:\SomeFolder\DB X';
3) In a macro, you can use the TransferDatabase method of the DoCmd object to link relevant tables and then run suitable append and update queries to synchronize.
4) VBA
http://www.techonthenet.com/access/questions/new_mdb.php
Given column names Col1, Col2, and Col3:
private static void Migrate(string dbConn1, string dbConn2) {
// DataTable to store your info into
var table = new DataTable();
// Modify your SELECT command as needed
string sqlSelect = "SELECT Col1, Col2, Col3 FROM aTableInOneAccessDatabase ";
// Notice this uses the connection string to DB1
using (var cmd = new OleDbCommand(sqlSelect, new OleDbConnection(dbConn1))) {
cmd.Connection.Open();
table.Load(cmd.ExecuteReader());
cmd.Connection.Close();
}
// Modify your INSERT command as needed
string sqlInsert = "INSERT INTO aTableInAnotherAccessDatabase " +
"(Col1, Col2, Col3) VALUES (#Col1, #Col2, #Col3) ";
// Notice this uses the connection string to DB2
using (var cmd = new OleDbCommand(sqlInsert, new OleDbConnection(dbConn2))) {
// Modify these database parameters to match the signatures in the new table
cmd.Parameters.Add("#Col1", DbType.Int32);
cmd.Parameters.Add("#Col2", DbType.String, 50);
cmd.Parameters.Add("#Col3", DbType.DateTime);
cmd.Connection.Open();
foreach (DataRow row in table.Rows) {
// Fill in each parameter with data from your table's row
cmd.Parameters["#Col1"].Value = row["Col1"];
cmd.Parameters["#Col2"].Value = row["Col2"];
cmd.Parameters["#Col3"].Value = row["Col3"];
// Insert that data
cmd.ExecuteNonQuery();
}
cmd.Connection.Close();
}
}
Now, I do not work with Access databases very often, so you may need to tweak something up there.
That should get you well on your way, though.
Worth noting:
If I remember correctly, Access does NOT pay attention to your OleDbParameter names! You could call them whatever you want, and in fact most people just use a question mark ? for the parameter fields.
So, you have to add and update these parameters in the same order that your statement calls them.
So, why did I name the parameters #Col1, #Col2, #Col3? Here, it just to help you and me understand where each parameter is intended to map to. It is also good practice to get into. If you ever migrate to a better database, hopefully it will pay attention to what the parameters are named.
I'm developing a classic WEBForms application in C# and when I have to authenticate the user, I read from SQL database the user data using a query like that:
SELECT userid,username,email,city FROM USERS where username='blablabla' and password='blablabla'
I want to use this sql query in my method that returns a DTO Object that I defined in my UserValue class.
I'm thinking to use a dataset to fill user data executing the query.
Is it the correct approach or is it too expensive and useless to use dataset to read one row from a query?
Can you advice me?
thanks
For getting only one record from database or one by one record from database,"Data Reader" is Good Approach.Check the sites below You can get clear Idea on Data Reader.
http://www.aspdotnet-suresh.com/2012/10/aspnet-difference-between-datareader.html
http://msdn.microsoft.com/en-us/library/haa3afyz.aspx
http://www.akadia.com/services/dotnet_data_reader.html
Here's a code snippet (this is for MS SQL, but other flavors of SQL should be similar) to illustrate what I'm talking about in my comment:
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
SqlCommand cmd = new SqlCommand("SELECT userid,username,email,city FROM USERS where username=#username and password=#password", con);
cmd.Paramters.AddWithValue("#username", username);
cmd.Parameters.AddWithValue("#password", password);
cmd.CommandType = CommandType.Text;
UserInfo info = new UserInfo();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
if (rdr.HasRows)
{
rdr.Read(); // get the first row
info.UserID = rdr.GetInt32(0);
info.UserName = rdr.GetString(1);
info.Email = rdr.GetString(2);
info.City = rdr.GetString(3);
}
}
}
This example also shows how to do parameterized queries, which are essential for preventing SQL Injection attacks.
Also, rather than looping through the reader, I check to see if it has rows and if it does I read the first row only (and since you're dealing with user information there should theoretically be only one row) and populate the DTO.
Hopefully this will illustrate my comment to your question.
I'm trying to learn about C# with SQL CE so that my program can remember stuff.
I have created a database and can connect to it:
SqlCeConnection conn =
new SqlCeConnection(#"Data Source=|DataDirectory|\dbJournal.sdf");
conn.Open();
And it connects right, I guess cause if I rename the dbJournal.sdf to something wrong it doesn't debug right.
Let's say I want to make a simple SELECT query.
(SELECT * FROM tblJournal)
How is that done?
What about a simple insert?
(INSERT TO tblJournal (column1, column2, column2) VALUES
(value1, value2, value3))
I'm used to PHP and MySQL (as you properly can see :o))
#Chuck mentions EntityFramework which simplifies things and does all the work of writing the sql for you.
But there is a basic ADO.NET approach here which I will describe below.
The classes follow a standard pattern so to insert/read from sql server or other databases there are exact replica classes like SqlConnection or OleDbConnection and OleDbCommand etc
This is the most barebones ado.net approach:
using( SqlCeConnection conn =
new SqlCeConnection(#"Data Source=|DataDirectory|\dbJournal.sdf") )
using( SqlCeCommand cmd = conn.CreateCommand() )
{
conn.Open();
//commands represent a query or a stored procedure
cmd.CommandText = "SELECT * FROM tblJournal";
using( SqlCeDataReader rd = cmd.ExecuteReader() )
{
//...read
}
conn.Close();
}
Then to read data :
while (rd.Read())
{//loop through the records one by one
//0 gets the first columns data for this record
//as an INT
rd.GetInt32(0);
//gets the second column as a string
rd.GetString(1);
}
A nice and quicker way to read data is like this:
using( SqlCeDataAdapter adap =
new SqlCeDataAdapter("SELECT * FROM tblJournal", "your connection") )
{
//the adapter will open and close the connection for you.
DataTable dat = new DataTable();
adap.Fill(dat);
}
This gets the entire data in one shot into a DataTable class.
To insert data :
SqlCeCommand cmdInsert = conn.CreateCommand();
cmdInsert.CommandText = "INSERT TO tblJournal (column1, column2, column2)
VALUES (value1, value2, value3)";
cmdInsert.ExecuteNonQuery();
If you just start learning that i will suggest you to use LINQ to make that queries.
Here is MSDN article showing features of LINQ.
http://msdn.microsoft.com/en-us/library/bb425822.aspx
Using LINQ it will be simple to do every query. For example, you can write your select query like this
from journal in TblJournal select journal
or just
context.TblJournal
also in order to improve performence , you better keep the conncection open all the time when working with SQL CE (as opposed to other standard sql databases)
i have design an access query which seem like this:
SELECT Replace(names,'lion','kiss') AS Expr1
FROM table1;
the two values that is lion and kiss, which are temporary, now i want these to be two variables, so that i can pass value to it from c#.
how to call this query from c#, and pass it two values.
I am using access 2007.
Thanks for your help :)
Try something like this (I found this on the subject):
public void ReplaceColumnA(string oldvalue, string newvalue)
{
using(OleDbConnection connection1 = (OleDbConnection)DatabaseConnection.Instance.GetConnection())
{
connection1.Open();
using(OleDbCommand sqlcmd2 = new OleDbCommand("queryname", connection1))
{
sqlcmd2.Parameters.AddWithValue("param1", newvalue);
sqlcmd2.Parameters.AddWithValue("param2", oldvalue);
sqlcmd2.ExecuteNonQuery();
}
}
}
The Access query would look like this:
UPDATE [t]
SET [a] = ?
WHERE [a] = ?
The names of the parameters you pass on don't matter, it's the order you pass them as.
By using the "using" statement you are ensure .NET is properly releasing the connections and resources.
Additionally I STRONGLY recommend switching to SQL Server Express Edition. It's free and a LOT more potent than what you can cook up in Access. Really, you're just shooting yourself in the foot continuing in Access...
You execute it like this:
sqlcmd2.ExecuteNonQuery();
I think you need to modify code like this
string q = "SELECT Replace(names,'{0}','{1}') AS Expr1 FROM table1";
//You can provide any values instead of LION and KISS
string query = string.format(q,"LION","KISS")
using(OleDbConnection cnn = (OleDbConnection)DatabaseConnection.Instance.GetConnection())
{
cnn.Open();
using(OleDbCommand cmd = new OleDbCommand(query, cnn))
{
OleDbDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
Console.WriteLine(reader["Expr1"].toString());
}
}
}