I want to display information of user stored in a MS Access database. The user enters his userid and on clicking a button following function is called. But no data is being displayed. What am I doing wrong ?
System.Data.OleDb.OleDbConnection con;
System.Data.OleDb.OleDbDataAdapter da;
protected void Button1_Click(object sender, EventArgs e)
{
con = new System.Data.OleDb.OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\sam\\Desktop\\mydb.mdb";
con.Open();
string sql = "SELECT * From Leave where userid="+Textbox1.Text;
da = new System.Data.OleDb.OleDbDataAdapter(sql, con);
DataTable t = new DataTable();
da.Fill(t);
GridView1.DataSource = t;
con.Close();
}
You need to call GridView1.DataBind()
GridView1.DataSource = t;
GridView1.DataBind();
Just a side-note, it is good practice to wrap your connection with using
using(con = new System.Data.OleDb.OleDbConnection())
{
con = new System.Data.OleDb.OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\sam\\Desktop\\mydb.mdb";
con.Open();
...
...
}
This ensures your connection is properly disposed after use
You should use bind function:
protected void Button1_Click(object sender, EventArgs e)
{
con = new System.Data.OleDb.OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=C:\\Users\\sam\\Desktop\\mydb.mdb";
con.Open();
string sql = "SELECT * From Leave where userid="+Textbox1.Text;
da = new System.Data.OleDb.OleDbDataAdapter(sql, con);
DataTable t = new DataTable();
da.Fill(t);
GridView1.DataSource = t;
GridView1.DataBind();
con.Close();
}
First off, please, please please don't concatenate your WHERE parameters in your SQL. Use Parameters. Second, Add a "using System.Data.OleDb" statement at the top of your module, so that you are not having to type things like:
System.Data.OleDb.OleDbDataAdapter
Over and over again.
Try the following code. Personally, when I have to work with data tables and such, I prefer to avoid all the DataAdapter nonsense, and keep it as simple as possible.
Note in the code below:
the "using" blocks. These place the variables created within them inside their own scope, and take care of disposal and such for you.
I used an OleDb Parameter instead of concatenating criteria. This is a much safer way to do things, and creates much cleaner and more readable code as well, especially in cases where you have several criteria in your WHERE clause.
I assume your UserID input is a string, since you are grabbing the value from a Textbox. If it is in fact an int value (such as an auto-incrementing id in MS Access) you will need to use an int data type instead. You may have to mess with it a little. When you are still figuring this stuff out, it can be a bit painful. However, using parameters increases security and maintainability.
Once you have obtained a data table as the return from the MyUsers method, you should be able to simply set the data source of your Gridview. If you have difficulties still, do as Steve suggests and check the Autogenerate columns property in the designer, or set it in code.
Not that I have moved the connection string to the project Properties/Settings. You should find this in the solution designer. Place your connection string there, in one spot, and you can obtain it from anywhere in your code. If you later change the connection string (such as moving your Db to another computer, server share, etc) you need only change it in one place.
SAMPLE CODE:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb; // put this here, and stop writing long namespaces inline
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Where possible, move code out of specific event handlers
// into methods which can be re-used from other client code.
// Here, I pulled the actual data access out into separate methods,
// and simply call it from the event handler:
this.LoadGridView(textBox1.Text);
}
private void LoadGridView(string UserID)
{
// Now we can load the gridview from other places in our
// code if needed:
this.dataGridView1.DataSource = this.MyUsers(UserID);
}
private DataTable MyUsers(string UserID)
{
var dt = new DataTable();
// Use a SQL Paramenter instead of concatenating criteria:
string SQL = "SELECT * FROM Leave WHERE userid = #UserID";
// The "using" statement limits the scope of the connection and command variables, and handles disposal
// of resources. Also note, the connection string is obtained from the project properties file:
using(OleDbConnection cn = new OleDbConnection(Properties.Settings.Default.MyConnectionString))
{
using (var cmd = new OleDbCommand(SQL, cn))
{
// For simpler things, you can use the "AddWithValue" method to initialize a new parameter,
// add it to the Parameters collection of the OleDBCommand object, and set the value:
cmd.Parameters.AddWithValue("#UserID", UserID);
// Get in, get out, get done:
cn.Open();
dt.Load(cmd.ExecuteReader());
cn.Close();
}
}
return dt;
}
}
}
Hope that helps. It's not how everyone might do it, but I have found it provides maximum flexibility, when you must work with MS Access.
Related
I am a beginner at C# and .NET oop concepts. I want to load the datagridview. I don't know how to pass the data. What I tried so far I attached below.
I created a class std
public void get()
{
SqlConnection con = new SqlConnection("server =.; initial catalog=testdb; User ID=sa; Password=123");
string sql = "select * from std";
con.Open();
SqlCommand cm = new SqlCommand(sql, con);
SqlDataReader dr = cm.ExecuteReader();
while ( dr.Read())
{
string stname = dr["st_name"].ToString();
string nicnum = dr["nic"].ToString();
}
con.Close();
}
Form: I am getting data like this way
std ss = new std();
ss.get();
dataGridView1.Rows.Clear();
If I wrote like this way how to pass data into the datagridview columns? I am stuck in this area
It's easier like this:
public void FillGrid()
{
var dt = new DataTable();
var da = new SqlDataAdapter("select * from std", "server =.; initial catalog=testdb; User ID=sa; Password=123");
da.Fill(dt);
dataGridView1.DataSource = dt;
}
but if you're going to use such a low level method of database access you should consider adding a DataSet type of file to your project; visual studio will write all this code and more for you with a few mouse clicks, and it makes a good job of creating tables and adapters that are a lot easier to work with
you have made multiple mistakes. First you read data wirh dataraeader and in every iteration define two stname and nimnum variables like. So when loop ends variables are destroyed. You have to define data table and read data by dataraeader and and add them to it row by row. Or read by sqldataadapter and read it immediately and pass to datatable object.Finnaly you pass datatable as return object of function. Use this vala as datasource of datagridview property if I'm not wrong.
I have a table which has the results of student's marks for particular modules (classes).
I take the mark percentage and multiply it against a value from the assessment table (based on the assessment ID). This part all works fine.
I tried to write a loop using the SQL data reader, to add up all the values FOR EACH MODULE. However, I can only seem to add up all the values altogether for a particular user (it's in the where clause). I can't put the moduleID = 1 in the WHERE clause because I need to see all results at once.
Here's the code I've already attempted, which adds up all the values for the user.
//set-up object to use the web.config file
string connectionString = WebConfigurationManager.ConnectionStrings["QSISConnection"].ConnectionString;
//set-up connection object called 'myConnection'
SqlConnection myConnection = new SqlConnection(connectionString);
// open database communication
myConnection.Open();
// create the SQL statement
string query = "SELECT ModuleAssessmentUser.ModuleID, ModuleAssessmentUser.AssessmentID, MarkPercentage * Assessment.AssessmentWeighting AS FinalMark FROM ModuleAssessmentUser INNER JOIN[Assessment] ON(Assessment.AssessmentID = ModuleAssessmentUser.AssessmentID) WHERE (ModuleAssessmentUser.UserID = 2)";
// set-up SQL command and use the SQL and myConnection object
SqlCommand myCommand = new SqlCommand(query, myConnection);
// create a SqlDataReader object that asks for data from a table
SqlDataReader rdr = myCommand.ExecuteReader();
// create variable to add column values
int totalmark = 0;
// when in read mode ask for data
while (rdr.Read())
{
// put variable value from moduleID column in local variable
string usermodule = rdr["ModuleID"].ToString();
// needs to be a text control called 'moduleid' on the aspx web page
modulenumber.Text = usermodule.ToString();
// get value of your weighting
int fmark = Convert.ToInt32(rdr["FinalMark"]);
// update the moduleweighting variable by adding the value in the column FinalMark
// this is in a loop so should accumulate the values
totalmark = totalmark + fmark;
result.Text = totalmark.ToString();
}
// once the adding up has been added up display total in final text box
// create a text control on aspx called 'result'
// need to convert int to string to display in text control
myConnection.Close();
I am still quite new to C# and ASP.NET, so any advice is appreciated.
Thanks in advance
Try code below :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace WindowsFormsApplication12
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//set-up object to use the web.config file
string connectionString = WebConfigurationManager.ConnectionStrings["QSISConnection"].ConnectionString;
//set-up connection object called 'myConnection'
SqlConnection myConnection = new SqlConnection(connectionString);
// open database communication
myConnection.Open();
//create the SQL statement
string query = "SELECT ModuleAssessmentUser.ModuleID, ModuleAssessmentUser.AssessmentID, MarkPercentage * Assessment.AssessmentWeighting AS FinalMark FROM ModuleAssessmentUser INNER JOIN[Assessment] ON(Assessment.AssessmentID = ModuleAssessmentUser.AssessmentID) WHERE (ModuleAssessmentUser.UserID = 2)";
//set-up SQL command and use the SQL and myConnection object
SqlCommand myCommand = new SqlCommand(query, myConnection);
//create a sqldatareader object that asks for dats from a table
SqlDataAdapter adapter = new SqlDataAdapter(myCommand);
DataTable dt = new DataTable();
adapter.Fill(dt);
dataGridView1.DataSource = dt;
int markPercentage = dt.AsEnumerable().Sum(x => x.Field<int>("MarkPercentage"));
}
}
}
Guys I searched around like hell but nothing could help me so I think it's time to ask. Before I write to problem, I need to say that I need it's solution asap because it's a project that I have to give tomorrow and I stuck on the same subject since ages and still losing time.
OK here it is;
I need to add a book to a library system, at first phase I add the standard book features which has only "one value" like (name, page number, publishing time, publisherID etc) but as wanted by me book MAY HAVE MULTIPLE WRITERS AND CATEGORIES which killed me and still I can't resolve. I tried to add book to it's (books) table then with the information i got from that i did an other insert op. to (bookWriters) table. While I check it, compiler does everything in order without error but when I check table from SQL Server there is nothing.
Here is what I tried to do;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
namespace Project_
{
public partial class addBook: Form
{
public addBook()
{
InitializeComponent();
}
public main refForm;
int chosenWritersNumber; //how many writers have selected on listbox
int[] writers= { }; // an array list that i keep writerIDs that comes from class
int ind = 0;
int insertedBookID; // to catch latest added book's ID
int chosenWriterID; // writer that will be added
private void bookAddingPreps()
{
chosenWritersNumber = lstWriters.SelectedItems.Count;
Array.Resize<int>(ref writers, chosenWritersNumber );
for (int i = 0; i < chosenWritersNumber ; i++)
{
writers[i] = ((X_Writers)lstWriters.SelectedItems[i]).XWriterID;
}
}
private void addMainBookInfos()
{
SqlConnection con = new SqlConnection(Conn.Activated);
SqlCommand com = new SqlCommand("AddBook", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#BookISBN", txtISBN.Text);
con.Close();
}
private void catchAddedBookID()
{
SqlConnection con = new SqlConnection(Conn.Activated);
SqlCommand com = new SqlCommand("catchBookID", con);
com.CommandType = CommandType.StoredProcedure;
con.Open();
SqlDataReader dr = com.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
insertedBookID = dr.GetInt32(0);
}
}
dr.Close();
con.Close();
}
private void addWritersOfTheBook()
{
chosenWriterID = writers[ind];
SqlConnection con = new SqlConnection(Conn.Activated);
SqlCommand com = new SqlCommand("addBookWriters", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#BookID", insertedBookID);
com.Parameters.AddWithValue("#WriterID", chosenWriterID);
con.Close();
}
I call these methods on click of a button. You see also stored procedure names but as I checked they all correct, there must be a mistake in this page that I still cant see but if it's needed I can add what procedures writes but they all tested and seems working.
So as i said, when i do this, as ind = 0, a writer should have been added, break point shows everything is ok and compiler doesnt show any errors but when I check sql server table, its empty.
Written in C# with using Visual Studio 2010 Ultimate and SQL Server 2008 Dev.
Thanks
You forget to execute your SqlCommand's. Make a call to command.ExecuteNonReader(); to execute it without expecting any results. see: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.aspx
Apart form that, dont forget to dispose the resources acquired in your methods. Something like:
private void addMainBookInfos()
{
using (SqlConnection con = new SqlConnection(Conn.Activated))
using (SqlCommand com = new SqlCommand("AddBook", con))
{
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#BookISBN", txtISBN.Text);
com.ExecuteNonQuery()
// close can be omitted since you are already using the 'using' statement which automatically closes the connection
con.Close();
}
}
Fairly new to C#, anyway, I have this Initialise method that I've written, it basically creates a connection to a MS2007 Access Database, fills a DataSet with the 4 DataTables that are the result of some queries.
public frmDBCompareForm()
{
///
/// Required for Windows Form Design support
///
InitializeComponent();
frmDBCompareForm_Initialize();
//
// TODO: Add any constructor code
//
if (_InstancePtr == null) _InstancePtr = this;
}
And the start of the Initialise Method, including one of the DataTables being filled:
private void frmDBCompareForm_Initialize()
{
// Fill DataSet with 3 DataTables, these tables will be
// made up of the from sQuery.
try
{
// Create a new DataSet
DataSet dsSite1 = new DataSet();
// Set up the connection strings to HCAlias.accdb
OleDbConnection con = new OleDbConnection();
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\HCAlias.accdb;Persist Security Info=False;";
con.Open();
//
// Table 1 - dtSite1Name [cmbSite1]
//
dtSite1Name = new DataTable();
string sQuery = "SELECT SourceName From Sites";
OleDbCommand cmdSite1Name = new OleDbCommand(sQuery, con);
OleDbDataAdapter myDASite1Name = new OleDbDataAdapter(cmdSite1Name);
myDASite1Name.Fill(dsSite1, "dtSite1Name");
cmbSite1.DataSource = dtSite1Name;
cmbSite2.DataSource = dtSite1Name;
Could anyone point me in the right direction for going about this the way I have? Any tips or advice to get that connection issue fixed? I've been Googling like a boss, but can't seem to find the exact issue that I'm having.
You also need to close your connection .
Add also on your finally block with:
using (var con = new OleDbConnection())
{
con.Open();
using (var cmd = new OleDbCommand("sqlquery", conn))
{
try
{
//do Stuff here
}
catch (OleDbException)
{
throw;
}
}
}
regards
This error is caused by leaving connections open. It won't necessarily happen right away but always after the same number of requests.
I suggest wrapping your IDisposable db classes with using statements:
using (OleDbConnection con = new OleDbConnection())
{
}
This will automatically call the implementation on the Dispose() method and close your connections.
From MSDN : "The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler." ... so you do not need your try catch finally
One of the problems I am having with c# is that there seems to be so much information online that I am having trouble finding the right answer to the most basic of questions.
I am trying to do something simple:
I have a button, I click it, it queries the database and populates a datagrid on my windows form.
private void button1_Click(object sender, EventArgs e)
{
SqlConnection c = new SqlConnection("Data Source = (local); Integrated Security = true; Initial Catalog = pubs; ");
c.Open();
// 2
// Create new DataAdapter
SqlCommand cmd = c.CreateCommand();
cmd.CommandText = #" SELECT * FROM Authors ";
SqlDataReader reader = cmd.ExecuteReader();
dataGridView1.DataSource = reader;
dataGridView1.DataBind();
}
Error 1 'System.Windows.Forms.DataGridView' does not contain a definition for 'DataBind' and no extension method 'DataBind' accepting a first argument of type 'System.Windows.Forms.DataGridView' could be found.....
I am probably missing a "using directive" but which one? Multiple Google searches tell me how to bind a Yahoo RSS Feed to a gridview or provide various obscure details on "using directives".
Maybe I am using the SqlDataReader incorrectly. Should I be using SqlAdapter instead? What happened to all the good basic tutorials online for windows c# forms? A few months ago I found a couple great tutorials, but they seem to have lost their pageranking and I cannot find them anymore using basic google searches.
You're not missing a using directive; it's just that the WinForms DataGridView doesn't have a DataBind method. Just assigning DataSource is enough to get the binding to happen; you don't need to call a method as well.
However, I don't think you can assign a SqlDataReader as the DataSource. According to the DataSource property documentation in MSDN, the DataSource must be an IList, an IListSource, an IBindingList or an IBindingListView. You will probably instead need to load the data into a DataTable or DataSet (or an object data source populated using an object-relational mapper), and use that as the DataSource.
Try this instead:
using (SqlConnection conn = new SqlConnection("your connection string"))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(#"SELECT * FROM Authors", conn))
{
using (SqlDataAdapter adap = new SqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
adap.Fill(dt);
dataGridView1.DataSource = dt;
}
}
}
The DataGridView does not have a DataBind() method because it doesn't need one. Setting the DataSource property handles the binding for you. The using() blocks will automatically close and dispose of everything for you as well.
Note: you should replace "your connection string" with a valid connection string. I left yours out of my sample to avoid the horizontal scrollbars, and I'm not sure yours is valid anyway. You may get a runtime error when you run the code using your connection string. www.connectionstrings.com is a great resource for figuring out a valid connection string.
Update: instead of the nested using() blocks, you can also do it like this:
using (SqlConnection conn = new SqlConnection("..."))
using (SqlCommand cmd = new SqlCommand(#" SELECT * FROM Authors", conn))
using (SqlDataAdapter adap = new SqlDataAdapter(cmd))
{
conn.Open();
DataTable dt = new DataTable();
adap.Fill(dt);
dataGridView1.DataSource = dt;
}
I prefer the nested style, but it's "half of one, six dozen of the other" to me. Typically, I would encapsulate code like this into a class (called "DataGetter" or whatever) with a static method like:
public static DataTable GetData(string query)
{
// do all the connecting and adapting and filling and so forth
}
so that the code in your button click would be as simple as:
dataGridView1.DataSource = DataGetter.GetData("SELECT * FROM AUTHORS");
However, I would not do this in any performance-critical section of my code, since you sometimes want to keep a SqlCommand object (and its SqlParameter collection) around between calls. You do not need to keep SqlConnection objects around between calls, thanks to connection pooling (in fact, you don't want to keep them around under any circumstances).