I'm trying to learn ADO.NET from "Programmers Heaven: C# School"
Thats the code I've created basing on that ebook, but running it causes:
System.NullReferenceException: Object reference not set to an instance of an object.
When trying to add Parameter (cmd.Parameters.Add("@" + col, OleDbType.Char, 0, col);) to the Command.
Could someone please point me whats wrong?
EDIT:
added the problem description
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;
namespace AdoNET
{
public partial class MainForm : Form
{
private OleDbConnection conn;
private OleDbDataAdapter dataAdapter;
private DataTable dataTable;
private DataSet ds;
private int currRec = 0;
private int totalRec = 0;
private bool insertSelected;
public MainForm()
{
InitializeComponent();
}
void BtnLoadTableClick(object sender, EventArgs e)
{
this.Cursor = Cursors.WaitCursor;
//create connection string
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db\\ProgrammersHeaven.mdb;";
//create connection
conn = new OleDbConnection(connectionString);
//define command
string commandString = "SELECT * FROM Article, Author WHERE Author.authorId = Article.authorId";
//create Data Adapter for communication with DB
dataAdapter = new OleDbDataAdapter(commandString, conn);
//create Data Set to store data offline
ds = new DataSet ();
//fill dataset (table prog) with data from dataAdapter
dataAdapter.Fill(ds, "prog");
//create and fill table dataTable
dataTable = ds.Tables["prog"];
currRec = 0;
totalRec = dataTable.Rows.Count;
FillControls();
InitializeCommands();
ToggleControls(true);
btnNext.Enabled = true;
btnPrevious.Enabled = true;
this.Cursor = Cursors.Default;
}
private void FillControls()
{
txtArticleID.Text = dataTable.Rows[currRec]["artId"].ToString();
txtArticleTitle.Text = dataTable.Rows[currRec]["title"].ToString();
txtArticleTopic.Text = dataTable.Rows[currRec]["topic"].ToString();
txtAuthorId.Text = dataTable.Rows[currRec]["Author.authorId"].ToString();
txtAuthorName.Text = dataTable.Rows[currRec]["name"].ToString();
txtNumOfLines.Text = dataTable.Rows[currRec]["lines"].ToString();
txtDateOfPublishing.Text = dataTable.Rows[currRec]["dateOfPublishing"].ToString();
}
void BtnNextClick(object sender, EventArgs e)
{
currRec++;
if (currRec>=totalRec)
{
currRec=0;
}
FillControls();
}
void BtnPreviousClick(object sender, EventArgs e)
{
currRec--;
if (currRec<0)
{
currRec=totalRec-1;
}
FillControls();
}
private void InitializeCommands()
{
//preparing INSERT command
dataAdapter.InsertCommand = conn.CreateCommand();
dataAdapter.InsertCommand.CommandText =
"INSERT INTO article " +
"(artId, title, topic, authorId, lines, dateOfPublishing) " +
"VALUES (@artId, @title, @topic, @authorId, @lines, @dateOfPublishing)";
AddParams(dataAdapter.InsertCommand, "artId", "title", "topic", "lines", "dateOfPublishing");
//preparing UPDATE command
dataAdapter.InsertCommand = conn.CreateCommand();
dataAdapter.InsertCommand.CommandText =
"UPDATE article SET" +
"title = @title, topic = @topic, lines = @lines, dateOfPublishing = @dateOfPublishing" +
"WHERE artId = @artId";
AddParams(dataAdapter.UpdateCommand, "artId", "title", "topic", "authorId", "lines", "dateOfPublishing");
//prepare DELETE command
dataAdapter.InsertCommand = conn.CreateCommand();
dataAdapter.InsertCommand.CommandText =
"DELETE FROM article WHERE artId = @artId";
AddParams(dataAdapter.DeleteCommand, "artId");
}
private void AddParams(OleDbCommand cmd, params string[] cols)
{
//adding hectic (?) parameters
foreach (string col in cols)
{
cmd.Parameters.Add("@" + col, OleDbType.Char, 0, col);
}
}
private void ToggleControls(bool val)
{
txtArticleTitle.ReadOnly = val;
txtArticleTopic.ReadOnly = val;
txtAuthorId.ReadOnly = val;
txtNumOfLines.ReadOnly = val;
txtDateOfPublishing.ReadOnly = val;
btnLoadTable.Enabled = val;
btnNext.Enabled = val;
btnPrevious.Enabled = val;
btnEditRecord.Enabled = val;
btnInsertRecord.Enabled = val;
btnDeleteRecord.Enabled = val;
btnSave.Enabled = !val;
btnCancel.Enabled = !val;
}
void BtnEditRecordClick(object sender, EventArgs e)
{
ToggleControls(false);
}
void BtnSaveClick(object sender, EventArgs e)
{
lblStatus.Text = "Saving Changes...";
this.Cursor = Cursors.WaitCursor;
DataRow row = dataTable.Rows[currRec];
row.BeginEdit();
row["title"] = txtArticleTitle.Text;
row["topic"] = txtArticleTopic.Text;
row["Article.authorId"] = txtAuthorId.Text;
row["lines"] = txtNumOfLines.Text;
row["dateOfPublishing"] = txtDateOfPublishing.Text;
row.EndEdit();
dataAdapter.Update(ds, "prog");
ds.AcceptChanges();
ToggleControls(true);
insertSelected = false;
this.Cursor = Cursors.Default;
lblStatus.Text = "Changes Saved";
}
void BtnCancelClick(object sender, EventArgs e)
{
if (insertSelected)
{
BtnDeleteRecordClick(null,null);
insertSelected=false;
}
FillControls();
ToggleControls(true);
}
void BtnDeleteRecordClick(object sender, EventArgs e)
{
DialogResult res = MessageBox.Show("Are you sure you want to delete the current record?",
"Confirm Record Deletion", MessageBoxButtons.YesNo);
if (res == DialogResult.Yes)
{
DataRow row = dataTable.Rows[currRec];
row.Delete();
dataAdapter.Update(ds, "prog");
ds.AcceptChanges();
lblStatus.Text = "Record Deleted";
totalRec--;
currRec = totalRec - 1;
FillControls();
}
}
void BtnInsertRecordClick(object sender, EventArgs e)
{
insertSelected = true;
//table must be loaded to create new row
DataRow row = dataTable.NewRow();
dataTable.Rows.Add(row);
totalRec = dataTable.Rows.Count;
currRec = totalRec-1;
row["artId"] = totalRec;
txtArticleID.Text = totalRec.ToString();
txtArticleTitle.Text = "";
txtArticleTopic.Text = "";
txtAuthorId.Text = "";
txtNumOfLines.Text = "";
txtDateOfPublishing.Text = DateTime.Now.Date.ToString();
ToggleControls(false);
}
}
}
I realize this is a couple of years late, but I wanted to add a few things after looking at this snippet of your code:
private void AddParams(OleDbCommand cmd, params string[] cols)
{
//adding hectic (?) parameters
foreach (string col in cols)
{
cmd.Parameters.Add("@" + col, OleDbType.Char, 0, col);
}
}
This is an OleDb data connection. I am not 100%, but I have never gotten parameters to work correctly when using the @
syntax for my parameter names like I do with Microsoft SQL . You might want to look at that. If I am not mistaken, OleDb uses the ?
symbol and ignores the names you assign. You MUST (at least as far as I can tell) add your parameters in the same order that they are declared in your SQL statement, as OleDb does not try to match them up - again, as best I can tell.
Also, you are specifying this OleDbTypeChar
parameter to be of size zero (0). That could be causing issues also if you make any attempt to assign values to your parameters.
Since this answer still pulls up in searches, I wanted to post something for others who wonder in to read your code like I just did.
In the InitializeCommands method, without creating the Update and Delete command you're sending into the AddParams method.
Change your dataAdapter.InsertCommand
to dataAdapter.UpdateCommand
and dataAdapter.DeleteCommand
in the corresponding places.
Side Note: If you read the error message, it is evident that you are trying to use some reference which refers to no object in the heap. In such cases, run through your code to find the guy who has no definition.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.