Im trying to fill a listview with data from my database but get a null reference exception when i load the listview. Im using MVC pattern.
Code in my data acces layer:
public List<Menu_Item> DB_Get_All_MenuItems()
{
string query = "SELECT * FROM [Menu_Items]";
SqlParameter[] sqlParameters = new SqlParameter[0];
return ReadTables(ExecuteSelectQuery(query, sqlParameters));
}
private List<Menu_Item> ReadTables(DataTable dataTable)
{
List<Menu_Item> menu_items = new List<Menu_Item>();
foreach (DataRow dr in dataTable.Rows)
{
Menu_Item menu_Item = new Menu_Item()
{
Menu_ID = (int)dr["Menu_ID"],
Naam = (string)dr["Naam"],
Prijs = (float)dr["Prijs"],
Voorraad = (int)dr["Voorraad"],
Categorie_ID = (int)dr["Catogorie_ID"]
};
menu_items.Add(menu_Item);
}
return menu_items;
}
I have checked and my SQL parameters are all spelled correctly
The exact error is: datatable.rows = 'datatable.rows' threw an exception of type 'system.nullreferenceexception'
My DateTable method looks like this
protected DataTable ExecuteSelectQuery(string query, params SqlParameter[] sqlParameters)
{
SqlCommand command = new SqlCommand();
DataTable dataTable;
DataSet dataSet = new DataSet();
try
{
command.Connection = OpenConnection();
command.CommandText = query;
command.Parameters.AddRange(sqlParameters);
command.ExecuteNonQuery();
adapter.SelectCommand = command;
adapter.Fill(dataSet);
dataTable = dataSet.Tables[0];
}
catch (SqlException e)
{
return null;
throw new Exception(e.ToString());
}
finally
{
CloseConnection();
}
return dataTable;
}
Check whether dataTable null or not
if(dataTable!=null && dataTable.Rows.Count > 0)
{
foreach (DataRow dr in dataTable.Rows)
{
Menu_Item menu_Item = new Menu_Item()
{
Menu_ID = (int)dr["Menu_ID"],
Naam = (string)dr["Naam"],
Prijs = (float)dr["Prijs"],
Voorraad = (int)dr["Voorraad"],
Categorie_ID = (int)dr["Catogorie_ID"]
};
menu_items.Add(menu_Item);
}
}
check if the datarows.count is null or not ...
Also in DB_Get_All_MenuItems() mention dbconnction string, sql command type, and datareader and all...first make sure the datas is returning in this function o/p....
You are trying to use something that is null. This means you either set it to null, or you never set it to anything at all.
Now, You can then place a breakpoint at every found location and run your program with the debugger attached. Every time the debugger breaks on such a breakpoint, you need to determine whether you expect the reference to be non-null.
Related
I am running a SQL Query and returning a DataSet - I want to iterate the info in the DataSet and assign the values to local variables. I have confirmed that my DataSet returns rows but my variables are not getting assigned for some reason. Can someone look at my syntax and assist with why this is occurring?
protected void GetSomeData()
{
string employeeid = this.txtemployeeid.Text;
DataSet empinfo = new DataSet();
empinfo = RunSqlQuery(employeeid);
this.txtemployeefirstname = empinfo.Tables[0].Rows[0]["employeefirstname"].ToString());
this.txtemployeelastname = empinfo.Tables[0].Rows[1]["employeelastname"].ToString());
this.txtemployeeaddress = empinfo.Tables[0].Rows[2]["employeeaddress"].ToString());
this.txt.employeephone = empinfo.Tables[0].Rows[3]["employeephone"].ToString());
}
public DataSet RunSqlQuery(string employeeid)
{
string sqlQuery = "Select employeefirstname, employeelastname, employeeaddress, employeephone from abcd where employeeid = "+employeeid+" and employeeid is not null";
try
{
connectionString = System.Configuration.ConfigurationManager.AppSettings[connectionString].ToString();
sqlDatabaseConnection = new SqlConnection(connectionString);
sqlCommand = new SqlCommand(sqlQuery, sqlDatabaseConnection);
sqlDatabaseConnection.Open();
sqlCommand.CommandTimeout = 0;
dataSet = new DataSet();
sqlDataAdapter = new SqlDataAdapter(sqlCommand);
sqlDataAdapter.Fill(dataSet, "Data");
return dataSet;
}
catch (Exception exception)
{
throw exception;
}
finally
{
sqlDatabaseConnection.Close();
sqlCommand.Dispose();
sqlDataAdapter.Dispose();
}
}
EDIT
By variables not getting assigned, I mean when I step through my code, it seems that the value returned from the database is not being populated into the empinfo.Tables[0].Rows[0]["employeefirstname"].ToString()); they are always null.
You're assigning the value to the textbox (at least, I assume txtemployeefirstname is a textbox). I think you mean txtemployeefirstname.text?
I'm typically used to traditional table in SQL where I have multiple columns with rows populated. I execute a stored procedure and store all the data in DataTable and loop through the table to get the results I need. For example,
public static DataTable getInfo (string sessionID)
{
try
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["SandBox"].ConnectionString);
SqlCommand cmd = new SqlCommand("GetSessionInfo", conn);
cmd.Parameters.AddWithValue("SessionGUID", sessionID);
cmd.CommandType = CommandType.StoredProcedure;
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
return dt;
}
catch (Exception)
{
throw;
}
}
I would load the DataTable:
DataTable infoTbl = new DataTable();
infoTbl = getInfo(lbldatabasesessionID.Text);
And I would use foreach loop to loop through the DataTable.
foreach (DataRow row in infoTbl.Rows)
{
string x = col.ToString();
}
The issue I run into is the database guy gave me a stored procedure that returns a different output (different from what I'm used to). It's a row based.
The only way I can access for example the First Name is if I hard code the position like:
string firstName = infoTbl.Rows[16][2].ToString();
I don't feel comfortable doing this since the position could potentially change. How would I access ElementValue by knowing the name knowing ElementType and ElementName?
Any suggestions?
Using DataSet:
string firstName = string.Empty;
DataRow row = table.Select("ElementType = 'Demographics' AND ElementName = 'FirstName'").FirstOrDefault();
if (row != null)
{
firstName = (string)row["ElementValue"];
}
Using Linq:
string firstName = table.AsEnumerable()
.Where(f => f.Field<string>("ElementType") == "Demographics" &&
f.Field<string>("ElementName") == "FirstName")
.Select(f => f.Field<string>("ElementValue")).FirstOrDefault();
I have a method which populates my ComboBox from a DataTable:
public string populateCompanyTransSellingEntityLookUp(ref System.Windows.Forms.ComboBox Combo, string Id, Contract Contract)
{
SqlCommand _comm = new SqlCommand();
_comm.Parameters.AddWithValue("#id", Id);
_comm.CommandText = "SELECT [name] FROM dbo.fnGetList(#id) ORDER BY [name]; ";
_comm.Connection = _conn;
_comm.CommandTimeout = _command_timeout;
DataTable dt = new DataTable();
try
{
SqlDataReader myReader = _comm.ExecuteReader();
dt.Load(myReader);
Combo.DataSource = dt;
Combo.DisplayMember = "name";
foreach (DataRow dr in dt.Rows)
{
if (dr["name"].ToString() == Contract.Company_Name.ToString())
{
Combo.Text = dr["company_int_name"].ToString();
}
}
}
catch
{
MessageBox.Show("Unable to populate Company Name LookUp");
}
return "";
}
I'm passing my saved value Contract.Company_Name into the forEach loop to find my required SelectedItem from the DataTable. The ComboBox is populated with my DataTable values from Combo.Datasource =dt; but my selected item isn't being set. The code compiles without exception. If I remove Datasource = dt;, theSelectedItemis set no problem. Why is theDatasourceoverriding mySelectedItem` and is there something I've missed with my binding?
Thanks all
At first you have to set the valueMember for sure. Then you can set the selectedValue Property instead of SelectedItem. The Item is one datasource record. So in your case it would be SelectedItem = dr! But iam not sure this is working.
Try this:
Combo.SelectedItem = dr;
I would suggest to use SelectedValue, then you don't need to loop through values "manually".
Also you don't need to use "heavy-weight" DataTable where you need just a collection of string values.
private IEnumerable<string> LoadNames(string id)
{
var query = "SELECT [name] FROM dbo.fnGetList(#id) ORDER BY [name]";
using (var connection = new SqlConnection("connectionString")
using (var command = new SqlCommand(query, connection)
{
// 36 is the size of the VarChar column in database(use your value)
command.Parameters.Add("#id", SqlDbType.VarChar, 36).Value = id;
connection.Open();
using (var reader = command.ExecuteReader())
{
var names = new List<string>();
while(reader.Read())
{
names.Add(reader.GetString(0));
}
return names;
}
}
}
public void Populate(ComboBox combobox, string id, Contract contract)
{
combobox.DataSource = LoadNames(id);
combobox.SelectedValue = contract.Copmpany_Name.ToString();
}
Few things to notice:
Dispose all objects which dealing with external resources (SqlConnection, SqlCommand and SqlDataReader)
Create SqlParameter with precise information about the type, for strings is important to provide size of the column in database. This information will improve SQL query performance on server side.
Don't pass combobox as a reference, populate method does not create new instance but only consume the given ComboBox instance.
Thank you for the help, I edited the code given that my problem was much more trivial.
public string populate_comboBox(ref System.Windows.Forms.ComboBox Combo)
{
SqlCommand _comm = new SqlCommand();
//edited for a simple one column sql query
_comm.CommandText ="SELECT [Column] FROM dbo.SQL_Table ORDER BY [Column];";
//MUST open sql connection to DB
SqlConnection conn = new SqlConnection(global_DB_String_Connection);
conn.Open();
_comm.Connection = conn;
DataTable dt = new DataTable();
try
{
SqlDataReader myReader = _comm.ExecuteReader();
dt.Load(myReader);
Combo.DataSource = dt;
Combo.DisplayMember = "ColumnName";
foreach (DataRow dr in dt.Rows)
{
//populates the combo box with query results
Combo.Text = dr["ColumnName"].ToString();
}
}
catch
{
Console.WriteLine("ComboBox Populate method has failed! ");
}
conn.Close();
return "";
}
i have created method for getting data from database. This method has DataTable as return type. When trying to call this method it is throwing me an exception of object reference is not set an instance of an object. Here is the method and how i am using it.
public DataTable executeSelect (String _query, SqlParameter[] sqlParameter)
{
SqlCommand myCommand = new SqlCommand();
DataTable dataTable = new DataTable();
dataTable = null;
DataSet ds = new DataSet();
try
{
myCommand.Connection = openConnection();
myCommand.CommandText = _query;
myCommand.Parameters.AddRange(sqlParameter);
myCommand.ExecuteNonQuery();
myadapter.SelectCommand = myCommand;
myadapter.Fill(ds);
dataTable = ds.Tables[0];
}
catch (SqlException e)
{
Console.Write( e.StackTrace.ToString());
return null;
}
finally
{
}
return dataTable;
}
Below code showing how above method is being used to result into a datatable
string sp_name = "sLot";
SqlParameter[] param = new SqlParameter[]{
new SqlParameter("#stype","ML"),
new SqlParameter("#ttype","B"),
new SqlParameter("#code",comp_code)
};
DataTable data = dbc.executeSelect(sp_name, param);
Note: This uses Stored Procedure name "sLot"
I assume that you are getting an excdeption, therefore you return null instead of a DataTable. You have to set CommandType to StoredProcedure if you use one.
myCommand.CommandType = CommandType.StoredProcedure;
Of course there are other possible reasons for a NullReferenceException, but you haven't provided enough informations. If the last line throws the exception as commented dbc is null. You can make executeSelect static or create an instance of the type where the method is declared.
I am trying to get the data from database by using the below code.....
if there is no data in the table it will always goes to
this statement
I am using mysql.net connector for getting the data and i am doing winforms applications
using c#
public DataTable sales(DateTime startdate, DateTime enddate)
{
const string sql = #"SELECT memberAccTran_Source as Category, sum(memberAccTran_Value) as Value
FROM memberacctrans
WHERE memberAccTran_DateTime BETWEEN #startdate AND #enddate
GROUP BY memberAccTran_Source";
return sqlexecution(startdate, enddate, sql);
}
and the below code is for return sqlexceution...function..
private static DataTable sqlexecution(DateTime startdate, DateTime enddate, string sql)
{
var table = new DataTable();
using (var conn = new MySql.Data.MySqlClient.MySqlConnection(connectionstring))
{
conn.Open();
var cmd = new MySql.Data.MySqlClient.MySqlCommand(sql, conn);
var ds = new DataSet();
var parameter = new MySql.Data.MySqlClient.MySqlParameter("#startdate", MySql.Data.MySqlClient.MySqlDbType.DateTime);
parameter.Direction = ParameterDirection.Input;
parameter.Value = startdate.ToString(dateformat);
cmd.Parameters.Add(parameter);
var parameter2 = new MySql.Data.MySqlClient.MySqlParameter("#enddate", MySql.Data.MySqlClient.MySqlDbType.DateTime);
parameter2.Direction = ParameterDirection.Input;
parameter2.Value = enddate.ToString(dateformat);
cmd.Parameters.Add(parameter2);
var da = new MySql.Data.MySqlClient.MySqlDataAdapter(cmd);
da.Fill(ds);
try
{
table = ds.Tables[0];
}
catch
{
table = null;
}
}
return table;
}
even if there is no data the process flow will goes to this line
table = ds.Tables[0];
how can i reduce this .....
would any one pls help on this....
In your case if you are think that catch block will get excuted if there is no row available than you are wrong because Even if there is no data once select query is get exucuted without exception it Creates datatable with the columns but with no rows.
for this i think you can make use of ds.table[0].rows.count property which return 0 if there is no row in datatable.
if ( ds.Tables[0].Rows.Count > 0 )
table = ds.Tables[0];
else
table=null;
It returns an empty table. This is common behavior. If you want to have table null you should check for the row count :
If ( ds.Tables[0].Rows.Count >. 0 )
table = ds.Tables[0];
Else
table=0
I'm not really sure what you're asking here ... I assume you want it to skip the table = ds.tables[0] line if there is no data?
if thats the case a try/catch wont work as it wont throw an exception ... try something like this instead ...
if(ds.Tables.Count > 0 && ds.Tables[0].Rows.Count >0)
{
table = ds.Tables[0];
}
else
{
table = null;
}