Передача DataAdapter.InsertCommand в метод приводит к нулевому значению для OleDbCommand - PullRequest
0 голосов
/ 07 мая 2010

Я пытаюсь выучить ADO.NET из "Небеса программистов: Школа C #"

Это код, который я создал на основе этой книги, но его запуск вызывает:

System.NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта.

При попытке добавить параметр (cmd.Parameters.Add ("@" + col, OleDbType.Char, 0, col);) в команду.

Может кто-нибудь указать мне, что не так?

EDIT:

добавлено описание проблемы

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);
    }
}

}

Ответы [ 2 ]

1 голос
/ 16 мая 2012

Я понимаю, что это на пару лет позже, но я хотел бы добавить несколько вещей после просмотра этого фрагмента кода:

private void AddParams(OleDbCommand cmd, params string[] cols)
{
    //adding hectic (?) parameters
    foreach (string col in cols)
    {
        cmd.Parameters.Add("@" + col, OleDbType.Char, 0, col);
    }
}
  • Это соединение для передачи данных OleDb. Я не на 100%, но я никогда не получал параметры для правильной работы при использовании синтаксиса @ для имен моих параметров, как я делаю с Microsoft SQL . Вы можете посмотреть на это. Если я не ошибаюсь, OleDb использует символ ? и игнорирует назначенные вами имена. Вы ДОЛЖНЫ (по крайней мере, насколько я могу судить) добавить свои параметры в том же порядке, в котором они объявлены в вашем операторе SQL , поскольку OleDb не пытается их сопоставить - опять же, насколько я могу судить.

  • Кроме того, вы указываете, что этот параметр OleDbTypeChar имеет нулевой размер (0). Это может также вызвать проблемы, если вы попытаетесь присвоить значения вашим параметрам.

Так как этот ответ все еще затягивается в поисках, я хотел опубликовать что-то для других, кому интересно читать ваш код, как я только что сделал.

1 голос
/ 07 мая 2010

В методе InitializeCommands без создания команды Update и Delete, которую вы отправляете в метод AddParams.

Измените dataAdapter.InsertCommand на dataAdapter.UpdateCommand и dataAdapter.DeleteCommand в соответствующих местах.

Примечание: Если вы прочитали сообщение об ошибке, очевидно, что вы пытаетесь использовать какую-то ссылку, которая не ссылается на объект в куче. В таких случаях запустите ваш код, чтобы найти парня, у которого нет определения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...