Kinda new to C#, I'm a bit confused with this issue I encountered in my codes for a school assignment. Trying to make a Room Activity chart in a winform for a school project where the SQL COUNT query I input counts the rows that have the value 'Room Activity' under the Event column but for some odd reason, I receive an ArgumentException wasn't handled error that tells me Column with name 'Event' was not found.
What am I doing wrong with my code?
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using System.Configuration;
using System.Data.SqlClient;
namespace Database_Chart_test
{
public partial class Form1 : Form
{
string strConnectionString = ConfigurationManager.ConnectionStrings["Database_Chart_test.Properties.Settings.LibrarySystemConnectionString"].ConnectionString;
public Form1()
{
InitializeComponent();
}
private void Activitychart_Click(object sender, EventArgs e)
{
}
private void RoomChart()
{
SqlConnection con = new SqlConnection(strConnectionString);
DataSet ds = new DataSet();
con.Open();
SqlDataAdapter adapt = new SqlDataAdapter("SELECT COUNT(*) FROM Log WHERE Event = 'Room Activity'", con);
adapt.Fill(ds);
Activitychart.DataSource = ds;
Activitychart.Series["WithActivity"].XValueMember = "Event";
Activitychart.Series["WithActivity"].YValueMembers = "Event";
con.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'librarySystemDataSet1.RoomsBooking' table. You can move, or remove it, as needed.
this.roomsBookingTableAdapter.Fill(this.librarySystemDataSet1.RoomsBooking);
// TODO: This line of code loads data into the 'librarySystemDataSet.Log' table. You can move, or remove it, as needed.
this.logTableAdapter.Fill(this.librarySystemDataSet.Log);
RoomChart();
}
}
}
After SELECT COUNT(*) FROM Log WHERE Event = 'Room Activity' executed, it will return a table with 1 column and 1 row (the count number).
Query result:
So the cause of the ArgumentException is that there is no column named Event in ds.Tables[0].
If you want to get the count, just call ExecuteScalar Method
using (SqlConnection conn = new SqlConnection(strConnectionString))
{
string strSQL = "SELECT COUNT(*) FROM Log WHERE Event = 'Room Activity'";
SqlCommand cmd = new SqlCommand(strSQL, conn);
conn.Open();
int count = (int)cmd.ExecuteScalar();
// add data point
Activitychart.Series["WithActivity"].Points.AddXY("Event", count);
Console.WriteLine("The count is {0}", count);
}
In addition, according to the code you provided, you are trying to use Event(a string) as YValueMembers. This does not seem reasonable. Generally, YValueMembers should be of numeric type.
Related
I am working on a C# Windows Forms application. I need to retrieve data into a datagridview from a SQL Server database.
How my program works:
Enter product code in the textbox
Click on the "Display button"
Then product details (name & price) related to the product code are loading to the first row of the datagridview.
I need to load the data to the very next row when this is done with another code.
But the problem is retrieving data is loading only in the first row by overwriting existing data. Not loading row by row.
How can I get data to the next row when it is searched by a product code without losing existing data in the datagridview? Any help would be much appreciated.
Image of my program
Here is my current code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace Retrieve_Data_In_Datagridview
{
public partial class Form1 : Form
{
SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=InventoryManagement;Integrated Security=True");
public Form1()
{
InitializeComponent();
}
private void bind_data()
{
SqlCommand cmd = new SqlCommand("SELECT [product_code], [product_name], [price], [discounted_price] FROM [product_tab] WHERE [product_code] = #parm1", conn);
cmd.Parameters.AddWithValue("#parm1", textBox1.Text);
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataTable dt = new DataTable();
dt.Clear();
da.Fill(dt);
dataGridView1.DataSource = dt;
//DataGridView1 navigating to next row
int nRow;
nRow = dataGridView1.CurrentCell.RowIndex;
if (nRow < dataGridView1.RowCount)
{
dataGridView1.CurrentCell = dataGridView1.Rows[++nRow].Cells[0];
}
}
private void button1_Click(object sender, EventArgs e)
{
bind_data();
}
}
}
The problem is basically that each time you do: dataGridView1.DataSource = dt; you change the source to a new Datatable that contains only the result of the last query.
Here is something like what you need:
[https://stackoverflow.com/questions/9608647/how-to-add-new-row-to-datagridview]
I have created a service based database in visual studio 2017. It works with a select statement but INSERT statement doesn't work. Here is my code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Configuration;
using System.Data.SqlClient;
namespace RestaurantApp
{
public partial class Form1 : Form
{
SqlConnection conn = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\SerinCafe.mdf;Integrated Security=True");
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
conn.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO Product (Id, ProductDescription, UnitPrice, SystemDate) Values (1,'Çay', 1, '01.01.2017')", conn);
cmd.ExecuteNonQuery();
SqlCommand cmd1 = new SqlCommand("SELECT * FROM Product", conn);
SqlDataAdapter da = new SqlDataAdapter(cmd1);
DataTable dt = new DataTable();
da.Fill(dt);
conn.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
I saw the same problem on different topics but there wasn't a clear solution that applies for me.
EDIT: On the SQL Server Object Explorer there is another database under the folder debug/bin. Now I checked it and I saw that data is inserted as I wanted. But it doesn't stay same. I changed the sql query as id = 3 and checked again. Previous data has gone. Newly inserted data is only there.
I have tested the code it works fine.Make sure you provided the connection string correctly.
I want to show my data that I have stored in a SQLite database in an ASP.net page which I code in C#.
I searched a lot on the internet and in my previous question someone showed me a really helpfull article. I used the code but it still doesn't work.
What I want is to get the first three columns in my gridview. So "woord", "vertaling" and "gebruiker" from the table "tbWoorden" should be displayed in the gridview.
This is my code:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Scripts_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnTest_Click(object sender, EventArgs e)
{
string connectionString =
#"Data Source=C:/Users/elias/Documents/Visual Studio 2017/WebSites/WebSite7/App_Data/overhoren.db";
using (var conn = new System.Data.SQLite.SQLiteConnection(connectionString))
{
conn.Open();
DataSet dsTest = new DataSet();
// Create a SELECT query.
string strSelectCmd = "SELECT woord,vertaling,gebruiker FROM tbWoorden";
// Create a SqlDataAdapter object
// SqlDataAdapter represents a set of data commands and a
// database connection that are used to fill the DataSet and
// update a SQL Server database.
SqlDataAdapter da = NewMethod(conn, strSelectCmd);
// Fill the DataTable named "Person" in DataSet with the rows
// returned by the query.new n
da.Fill(dsTest, "tbWoorden");
// Get the DataView from Person DataTable.
DataView dvPerson = dsTest.Tables["tbWoorden"].DefaultView;
// Set the sort column and sort order.
dvPerson.Sort = ViewState["SortExpression"].ToString();
// Bind the GridView control.
grdMijnLijsten.DataSource = dvPerson;
grdMijnLijsten.DataBind();
using (var command = new System.Data.SQLite.SQLiteCommand(conn))
{
command.Connection = conn;
command.CommandText =
#"SELECT[vertaling], [woord] FROM[tbWoorden] WHERE[woord] = 'ans'";
using (var reader = command.ExecuteReader())
{
string test = "";
}
}
}
}
private static SqlDataAdapter NewMethod(System.Data.SQLite.SQLiteConnection conn, string strSelectCmd)
{
return new SqlDataAdapter(strSelectCmd, conn);
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void grdMijnLijsten_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
The error I get is: cannot convert from 'System.Data.SQLite.SQLiteConnection' to 'string'.
The part that causes the error is the conn string in the NewMethod:
private static SqlDataAdapter NewMethod(System.Data.SQLite.SQLiteConnection conn, string strSelectCmd)
{
return new SqlDataAdapter(strSelectCmd, conn);
}
What do I have to change?
Thanks in advance, Elias
You have to use SQLiteDataAdapter (from the SQLite family) instead of SqlDataAdapter (which is part of the SQLClient family)
I am new to C# and need to create a little form application, that has two textboxes one that asks for a [File_ID] then when button is pressed send that number to a query and in another textbox display the output.
I have been playing around with it a bit, and have something like this. But it is not working. I am not sure if I should go on a different direction. I would REALLY appreciate your help.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace testing
{
public partial class Form1 : Form
{
String str,dr;
SqlConnection con = new SqlConnection("Data Source=USHOU2016\\USFi;Initial Catalog=HOU_2016_Project;Integrated Security=True");
SqlCommand cmd;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
con.Open();
str = "SELECT TOP 1,[Sender Name],[Subject] from [OLE DB Destination] WHERE [CHAT #] ='" + textBox1.Text + "'";
cmd = new SqlCommand(str, con);
// dr = cmd.ExecuteReader();
con.Close();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
textBox1.Text = cmd.ExecuteScalar().ToString();
}
}
}
Your SQL query syntax is wrong it should rather be below. You have a extra , after TOP 1 .. remove that
SELECT TOP 1 [Sender Name],[Subject] from [OLE DB Destination] WHERE...
Again in your button click you are just creating the command cmd = new SqlCommand(str, con); but never executing it. and just closing the connection.
In textBox2_TextChanged event handler you are trying to execute the query but connection has already gone. I think it's time you should consider reading about ADO.NET
This should do the trick. A couple of things to note:
since the button is executing your sql and populating the 2nd textbox, there's no need for the textbox_changed event
Using string concatenation to append your variables to your sql query is bad practice and makes your code susceptible to Sql Injection. Instead, parameterize your sql inputs as shown in the code below.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string query = "SELECT TOP 1,[Sender Name],[Subject] "
+ " from[OLE DB Destination] WHERE[CHAT #] = :chatId ";
using (SqlConnection con = new SqlConnection("Data Source=USHOU2016\\USFi;Initial Catalog=HOU_2016_Project;Integrated Security=True"))
{
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("chatId", textBox1.Text); //use Sql parameters to protect yourself against Sql Injection!
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
textBox2.Text = reader[0] + " " + reader[1]; //or however you want your output formatted
}
reader.close();
}
}
}
Here's a little background on what I'm doing...
I'm writing a C# web app. On the main page, I have a data input form with about 25 individual Dropdownlists. I created a table called options, and it's pretty simple (ID, Category, Option). Each option I create is categorized so my query will only include options that match the category I'm looking up. Each Category matches one of the 25 Dropdownlists I need to populate.
So I'm able to get a few of these populated on the form and they work great. I'm concerned that the re-writing of this code (with slight variation of the DDlist name and category name) will cause the code to be much longer. Is there a way I can create a class of it's own and pass parameters to the class so it only returns me data from the correct category and populates the correct Dropdownlist? Here's some sample code I have so far for 2 DD fields. The DDStationList and DDReqeustType are the names of 2 of the 25 Dropdownlists I have created:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Drawing;
namespace TEST
{
public partial class _Default : Page
{
//Main connection string
string SqlConn = ConfigurationManager.AppSettings["SqlConn"];
string qryRequestType = ConfigurationManager.AppSettings["qryRequestTypes"];
string qryStationNumbers = ConfigurationManager.AppSettings["qryStationNumbers"];
protected void Page_Load(object sender, EventArgs e)
{}
protected void BtnAddNew_Click(object sender, EventArgs e)
{
//GET Request Types
DataTable RequestTypes = new DataTable();
SqlConnection Conn = new SqlConnection(SqlConn);
{
SqlDataAdapter adapter = new SqlDataAdapter(qryRequestType, Conn);
adapter.Fill(RequestTypes);
DDRequestType.DataSource = RequestTypes;
DDRequestType.DataTextField = "Option";
DDRequestType.DataValueField = "Option";
DDRequestType.DataBind();
}
// Get Stations
DataTable Stations = new DataTable();
SqlConnection Conn = new SqlConnection(SqlConn);
{
SqlDataAdapter adapter = new SqlDataAdapter(qryStationNumbers, Conn);
adapter.Fill(Stations);
DDStationList.DataSource = Stations;
DDStationList.DataTextField = "Option";
DDStationList.DataValueField = "Option";
DDStationList.DataBind();
}
}
protected void BtnSubmit_Click(object sender, EventArgs e)
{
//More stuff to do here for submit code
}
}
}
Example queries from my config file that correspond to above code:
SELECT [Option] FROM Table WHERE Category = 'RequestType';
SELECT [Option] FROM Table WHERE Category = 'Station';
So, is it possible I can create a class that I can pass the Option's Category into that runs the query Like this:
SELECT [Option] FROM Table WHERE Category = #Category;
...and then populate the correct Dropdownlist (need to do this 25 times)?
If I'm not clear on my question, I'll be happy to explain further.
Why not create a stored procedure instead?
using (SqlConnection con = new SqlConnection(dc.Con)) {
using (SqlCommand cmd = new SqlCommand("sp_GetCategory", con)) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Category", SqlDbType.VarChar).Value = txtCategory.Text;
con.Open();
var results = cmd.ExecuteReader();
}
}
OR include the parameter
string sql = "SELECT [Option] FROM Table WHERE Category = #Category";
using (SqlConnection con = new SqlConnection(dc.Con)) {
using (SqlCommand cmd= new SqlCommand(sql, con)) {
cmd.Parameters.Add("#Category", SqlDbType.VarChar).Value = txtCategory.Text;
con.Open();
var results = cmd.ExecuteReader();
}
}
EDIT
class Category
{
/* properties */
/* method */
public List<Category> GetCategory(string selectedCategory)
{ /* Method statements here */ }
}