Reader always returns NULL - sql-server

I'm new to C#. I want to write an application that can easily connect to a SQL Server database. I have a separate DBConnection class, and I want to call this class from any form.
The problem is that my "reader" always returns Null.
class DBconnection
{
private SqlConnection conn;
private SqlCommand cmd;
private SqlDataReader rdr;
private DataTable dt;
private SqlConnection MyConnection
{
get
{
if (this.conn == null)
{
this.conn = new SqlConnection(DrivingSchool.Properties.Settings.Default.cdsConnectionString);
}
return conn;
}
}
private SqlCommand MyCommand
{
get
{
if (cmd == null)
{
cmd = new SqlCommand();
MyCommand.Connection = conn;
}
return cmd;
}
}
public DataTable RunQuery(string query)
{
dt = new DataTable();
MyCommand.CommandText = query;
MyCommand.Connection = conn;
MyConnection.Open();
rdr = MyCommand.ExecuteReader(CommandBehavior.CloseConnection);
if(rdr.HasRows)
{
dt.Load(rdr);
}
MyConnection.Close();
return dt;
}
}

It seems to me that in factoring out the creation of the connection and SqlCommand that you have over-complicated your code.
To fill a DataTable, you should use an SqlDataAdapter (or the appropriate DataAdapter for whatever database you use), something like this:
static public DataTable GetDataTableFromQuery(string queryString)
{
DataTable dt = null;
string connStr = DrivingSchool.Properties.Settings.Default.cdsConnectionString;
using (SqlDataAdapter da = new SqlDataAdapter(queryString, connStr))
{
da.Fill(dt);
}
return dt;
}

Related

InvalidOperationException: DataReader already active on this command

An error occurred while attempting to create a DB through the Uniy.
Below is a DLL file created by referring to "Mono.Data.Sqlite".
public class DbCon
{
private String Path;
private SqliteConnection connection;
private SqliteCommand Command;
public DbCon(String nPath)
{
Path = nPath;
}
private string getCoonectingString()
{
string strCon = String.Format(#"Data Source={0};Version=3;New=True;Compress=False;Read Only=False;MultipleActiveResultSets=True", Path);
return strCon;
}
public bool IsConnected()
{
if (connection != null && connection.State == System.Data.ConnectionState.Open)
return true;
return false;
}
public bool connect()
{
if (IsConnected() == true) return true;
connection = new SqliteConnection(getCoonectingString());
try
{
connection.Open();
if (connection.State == System.Data.ConnectionState.Open)
{
Command = new SqliteCommand();
Command.Connection = connection;
return true;
}
}
catch
{
return false;
}
return false;
}
private DataTable GetTable()
{
DataTable dataTable = new DataTable();
dataTable.Columns.Add("NAME", typeof(string));
dataTable.Columns.Add("EADATE", typeof(string));
dataTable.Columns.Add("LATIUDE", typeof(string));
dataTable.Columns.Add("HLTIUDE", typeof(string));
dataTable.Columns.Add("LRAD", typeof(Double));
dataTable.Columns.Add("NRAD", typeof(Double));
dataTable.Columns.Add("MRAD", typeof(Double));
dataTable.Columns.Add("NNL", typeof(string));
dataTable.Columns.Add("CREATDATE", typeof(string));
dataTable.Columns.Add("EDITDATE", typeof(string));
return dataTable;
}
/// <summary>
/// NAME
/// </summary>
/// <returns>DataTable</returns>
public DataTable GetNameListSel()
{
DataTable table = new DataTable();
table.Columns.Add("NAME", typeof(string));
String queryString = String.Format("SELECT DISTINCT NAME from IFPUG ");
Command.CommandText = queryString;
table.Load(Command.ExecuteReader());
Command.ExecuteReader().Close();
return table;
}
}
This script was taken by referring to Unity.
void Start()
{
string str = "C:/SEA.s3db";
DbCon nCon;
nCon = new DbCon(str);
bool result = nCon.connect();
Debug.Log(result);
if (result == true)
{
table = nCon.GetNameListSel();
Debug.Log("11");
}
else
{
Debug.Log("22");
}
}
I ran the function with the script above, but I checked to be connected, but I keep getting an error in the part where I run the function.
{InvalidOperationException: DataReader already active on this command}
I need your help. Please let me live.

Login for users of different positions

I am sort of new to login feature for projects and am trying to do logins for my group, which consists of 3 users, namely Nurse, Patient and Pharmacist. I think I am about to complete the loin process but I have a problem with one of my methods, getPosition() in my LoginDAO.cs. So far, I have not done any login codes for patient and pharmacist as i will need my group mates' parts for it to work, but shown below is what I have done. Somehow, login(string nric, string pw) works, but not getPosition(string nric). This is the error that i get from my error log:
Exception: Must declare the scalar variable "#paraNRIC". Source: LoginDAO.getPosition
Thanks in advance :D
protected void btnLogin_Click(object sender, EventArgs e)
{
login login = new login();
login.nric = tbLoginID.Text;
login.pw = tbPassword.Text;
if (login.userLogin(login.nric, login.pw))
{
if (login.getPosition(login.nric) == "Nurse")
{
Response.Redirect("Nurse.aspx");
}
else if (login.getPosition(login.nric) == "Patient")
{
Response.Redirect("Patient.aspx");
}
else if (login.getPosition(login.nric) == "Pharmacist")
{
Response.Redirect("PharmacistDisplay.aspx");
}
}
else
{
lblErr.Text = "Invalid account.";
}
}
public bool login(string nric, string pw)
{
bool flag = false;
SqlCommand cmd = new SqlCommand();
StringBuilder sqlStr = new StringBuilder();
sqlStr.AppendLine("SELECT Password from Position");
sqlStr.AppendLine("Where NRIC = #paraNRIC");
try
{
SqlConnection myconn = new SqlConnection(DBConnect);
cmd = new SqlCommand(sqlStr.ToString(), myconn);
cmd.Parameters.AddWithValue("#paraNRIC", nric);
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
if (dt == null)
{
flag = false;
}
else
{
string dbhashedpw = dt.Rows[0]["Password"].ToString();
flag = Helper.VerifyHash(pw, "SHA512", dbhashedpw);
}
}
catch (Exception exc)
{
logManager log = new logManager();
log.addLog("NurseDAO.login", sqlStr.ToString(), exc);
}
return flag;
}
public string getPosition(string nric)
{
string dbPosition = "";
int result = 0;
SqlCommand cmd = new SqlCommand();
StringBuilder sqlStr = new StringBuilder();
sqlStr.AppendLine("SELECT Position from Position ");
sqlStr.AppendLine("where NRIC = #paraNRIC");
cmd.Parameters.AddWithValue("#paraNRIC", nric);
try
{
SqlConnection myconn = new SqlConnection(DBConnect);
cmd = new SqlCommand(sqlStr.ToString(), myconn);
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
myconn.Open();
result = cmd.ExecuteNonQuery();
dbPosition = dt.Rows[0]["Position"].ToString();
myconn.Close();
}
catch (Exception exc)
{
logManager log = new logManager();
log.addLog("LoginDAO.getPosition", sqlStr.ToString(), exc);
}
return dbPosition;
`}
Your error is here:
SqlCommand cmd = new SqlCommand();
// lines omitted
cmd.Parameters.AddWithValue("#paraNRIC", nric);
try
{
SqlConnection myconn = new SqlConnection(DBConnect);
cmd = new SqlCommand(sqlStr.ToString(), myconn);
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
Note that you are instantiating cmd twice. The code adds the parameters to the first SqlCommand instance, but executes the second instance.
To resolve, ensure you declare the parameters on the instance of SqlCommand you invoke:
public string getPosition(string nric)
{
string dbPosition = "";
int result = 0;
// remove this line: SqlCommand cmd = new SqlCommand();
StringBuilder sqlStr = new StringBuilder();
sqlStr.AppendLine("SELECT Position from Position ");
sqlStr.AppendLine("where NRIC = #paraNRIC");
// move parameter declaration until after you declare cmd
try
{
SqlConnection myconn = new SqlConnection(DBConnect);
SqlCommand cmd = new SqlCommand(sqlStr.ToString(), myconn);
// add the parameters here:
cmd.Parameters.AddWithValue("#paraNRIC", nric);
// code continues
You could change this line
sqlStr.AppendLine("where NRIC = #paraNRIC");
To This
sqlStr.AppendLine("where NRIC = '" + nric + "'");
and avoid parameters altogether.

fill textbox on second combobox selection changed in cascading combobox in windows form using c#

I have 2 cascading combo-box in windows form application. I have textbox for price and unit. when I select first combobox, second combobox gets populated. I want textbox for price and unit to be filled only on second combobox selection.
My problem is when the form is loaded both textboxes are filled with values from table and not on combobox selection changed.
my code is:
private void Purchase_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'supplierDataSet.Supplier' table. You can move, or remove it, as needed.
this.supplierTableAdapter.Fill(this.supplierDataSet.Supplier);
fillName();
comboBoxName.SelectedIndex = -1;
}
private void fillName()
{
string str = "Select distinct Item_Name from Item";
using (SqlConnection con = new SqlConnection(#"Data Source=ashish-pc\;Initial Catalog=HMS;Integrated Security=True"))
{
using (SqlCommand cmd = new SqlCommand(str, con))
{
using (SqlDataAdapter adp = new SqlDataAdapter(cmd))
{
DataTable dtItem = new DataTable();
adp.Fill(dtItem);
comboBoxName.DataSource = dtItem;
comboBoxName.DisplayMember = "Item_Name";
comboBoxName.ValueMember = "Item_Name";
}
}
}
}
private void fillMake()
{
string str = "Select Item_Make from Item Where Item_Name=#Item_Name";
using (SqlConnection con = new SqlConnection(#"Data Source=ashish-pc\;Initial Catalog=HMS;Integrated Security=True"))
{
using (SqlCommand cmd = new SqlCommand(str, con))
{
cmd.Parameters.AddWithValue("#Item_Name", comboBoxName.Text);
using (SqlDataAdapter adp = new SqlDataAdapter(cmd))
{
DataTable dtItem = new DataTable();
adp.Fill(dtItem);
comboBoxMake.DataSource = dtItem;
comboBoxMake.ValueMember = "Item_Make";
comboBoxMake.DisplayMember = "Item_Make";
}
}
}
}
private void comboBoxName_SelectedIndexChanged_1(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(comboBoxName.Text))
{
comboBoxMake.Enabled = true;
fillMake();
comboBoxMake.SelectedIndex = -1;
}
}
private void comboBoxMake_SelectedIndexChanged_1(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(comboBoxMake.Text))
{
textBoxPrice.Enabled = true;
textBoxUoM.Enabled = true;
}
SqlConnection con = new SqlConnection(#"Data Source=ashish-pc\;Initial Catalog=HMS;Integrated Security=True");
SqlCommand cmd = new SqlCommand("Select * from Item Where Item_Make='" + comboBoxMake.Text + "' AND Item_Name='" + comboBoxName.Text + "'", con);
SqlDataReader reader;
try
{
if (con.State == ConnectionState.Closed)
{
con.Open();
}
reader = cmd.ExecuteReader();
while (reader.Read())
{
textBoxPrice.Text = Convert.ToString(reader["Price"]);
textBoxUoM.Text = Convert.ToString(reader["Unit"]);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
}
I am stuck here. please help.
Try changing SelectedIndex = -1 to SelectedItem = -1 in Purchase_Load and ComboBox1_SelectedIndexChanged.

ComboBox Shows System.Data.DataRow (MVC)

My Combobox does not show me the values in my SQL-Attribute "TimeBlock", instead it shows System.Data.DataRow 5 Times. What is wrong with my code?
Code:
//DAL:
public class DAL{
string ConnectionString = "server=ICSSQL13\\Grupp28,1528; Trusted_Connection=yes; database=Yoloswag";
public DataTable StoreSqlDataInComboBoxTP()
{
SqlConnection Conn = new SqlConnection(ConnectionString);
Conn.Open();
string StoreSqlDataInComboBoxTP = "SELECT TimeBlock FROM TimePeriod GROUP BY TimeBlock";
SqlCommand Cmd = new SqlCommand(StoreSqlDataInComboBoxTP, Conn);
SqlDataAdapter Adapter = new SqlDataAdapter(Cmd);
DataSet DSet = new DataSet();
Adapter.Fill(DSet);
Adapter.Dispose();
Cmd.Dispose();
Conn.Close();
Conn.Close();
return DSet.Tables[0];
}
}
//Controller:
public class Controller
{
DAL Dal = new DAL();
public DataTable storesqldataincomboboxtp()
{
return Dal.StoreSqlDataInComboBoxTP();
}
}
//View:
public partial class Booking : Form
{
Controller controller = new Controller();
DataTable DTable = new DataTable();
DataSet DSet = new DataSet();
//Ignore string UserName
public Booking(string UserName){
DTable = controller.storesqldataincomboboxtp();
if (DTable.Rows.Count > 0)
{
for (int i = 0; i < DTable.Rows.Count; i++)
{
CBTime.Items.Add(DTable.Rows[i].ToString());
}
}
}
}
Instead of the 5 System.Data.DataRow I want to show what is stored in "TimeBlock".
"SELECT TimeBlock From TimePeriod GROUP BY TimeBlock" shows:
"08-00 - 10:00"
"10:00 - 12:00"
"12:00 - 14:00"
"14:00 - 16:00"
"16:00 - 18:00"
How can i solve this?
Thanks
You are not getting to the Field level when you are calling the Add() on CBTime. Something like this within your conditional checking that your table has rows would work:
foreach (DataRow dRow in DTable.Rows)
{
CBTime.Items.Add(dRow["TimeBlock"]);
}

CRUD operation in MVC with out Entity framework

Hi I am beginner in MVC , I am trying to achieve CRUD operation in MVC using SQL with out Entity Framework or LINQ-SQL class. I done well with insert and getting the details of the selected table but when coming to Edit, details and delete I am confused how to perform so can some one help me out.
This is my code
Create a new Employee
public ActionResult Index(Test test)
{
try
{
if (ModelState.IsValid)
{
test.insert(test);
test.Name = "";
test.LastName = "";
}
}
catch (Exception)
{
}
return View(test);
}
Display all results
public ActionResult display()
{
Test tst = new Test();
return View(tst.getList());
}
This is my code in class file
public class Test
{
public int EmpID { get; set; }
[Required]
[DisplayName("Name")]
public string Name { get; set; }
[Required]
[DisplayName("LastName")]
public string LastName { get; set; }
string strConnection = ConfigurationManager.ConnectionStrings["SomeDataBase"].ConnectionString.ToString();
public void insert(Test test)
{
using (SqlConnection con = new SqlConnection(strConnection))
{
SqlCommand cmd = new SqlCommand("insert into Employee values('" + test.Name + "','" + test.LastName + "')", con);
con.Open();
cmd.ExecuteNonQuery();
}
}
public List<Test> getList()
{
List<Test> _lstPoducts = new List<Test>();
SqlConnection con = new SqlConnection(strConnection);
SqlCommand cmd = new SqlCommand("select * from Employee", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Test _Products = new Test();
_Products.EmpID = Convert.ToInt16(dr["EmpID"].ToString());
_Products.Name = dr["FirstName"].ToString();
_Products.LastName = dr["LastName"].ToString();
_lstPoducts.Add(_Products);
}
return _lstPoducts;
}
public List<Test> edit(int id)
{
List<Test> _lstPoducts = new List<Test>();
SqlConnection con = new SqlConnection(strConnection);
SqlCommand cmd = new SqlCommand("select * from Employee where EmpID='" + id + "'", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Test _Products = new Test();
_Products.EmpID = Convert.ToInt16(dr["EmpID"].ToString());
_Products.Name = dr["FirstName"].ToString();
_Products.LastName = dr["LastName"].ToString();
_lstPoducts.Add(_Products);
}
return _lstPoducts;
}
}
Can some one help me how to do the remaining operations like Details, Edit update and Delete.
for Details you can use
public Test details(int id)
{
Test _products = new Test();
SqlConnection con = new SqlConnection(strConnection);
SqlCommand cmd = new SqlCommand("select * from Employee where EmpID='" + id + "'", con);
con.Open();
try{
SqlDataReader dr = cmd.ExecuteReader();
_products.EmpID = Convert.ToInt16(dr["EmpID"].ToString());
_products.Name = dr["FirstName"].ToString();
_products.LastName = dr["LastName"].ToString();
}
catch(exception ex)
{
/* Do Some Stuff */
}
return _products;
}
And from your Controller
public ActionResult Details(int id)
{
Test tst = new Test();
return tst.Details(id);
}
for Edit you can use
public Bool Edit(test tst)
{
SqlConnection con = new SqlConnection(strConnection);
SqlCommand cmd = new SqlCommand("UPDATE TABLE Employee SET FirstName='"+tst.Name+"',Lastname='"+tst.LastName+"' where EmpID='" + tst.EmpId + "'", con);
con.Open();
try{
SqlDataReader dr = cmd.ExecuteReader();
return true;
}
catch(exception ex)
{
/* Do Some Stuff */
}
}
And from your Controller
public ActionResult Edit(test tsts)
{
Test tst = new Test();
return tst.Edit(tsts);
}
and proceed similarly for the rest of the cases

Resources