41 messaggi dal 09 gennaio 2012
Salve
studiando un listato di un esercizio mi sono trovato con un errore per il quale non ne vengo accapo: mi dice che alla riga 45
"L'argomento 'column' non puo' essere null.Nome parametro: column"
Si tratta di una finestra con 2 form : uno che mostra i dati della tabella Ordini e l'altro della tabella dettagli ordini del db Northwind.
Cosa sbaglio ?

ecco il codice completo


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SimpleDataEntryForm {
public partial class Form1 : Form {
public string connString;
public string query1;
public string query2;
public OleDbDataAdapter orders_dAdapter;
public OleDbDataAdapter order_details_dAdapter;
public DataSet NW_Orders;
public OleDbCommandBuilder cBuilder;
public OleDbCommandBuilder cBuilder1;
public BindingSource orders_bndSource;
public BindingSource order_details_bndSource;
public Boolean saveprompt;

public Form1() {
InitializeComponent();
saveprompt = false;
connString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=C:\\studio C#\\FormInserimentoDati\\nordWindo.mdb";
NW_Orders = new DataSet();
query1 = "SELECT * FROM Orders";
query2 = "Select * from [Order Details]";
orders_dAdapter = new OleDbDataAdapter(query1, connString);
order_details_dAdapter = new OleDbDataAdapter(query2, connString);

cBuilder = new OleDbCommandBuilder(orders_dAdapter);
cBuilder.QuotePrefix = "[";
cBuilder.QuoteSuffix = "]";
cBuilder1 = new OleDbCommandBuilder(order_details_dAdapter);
cBuilder1.QuotePrefix = "[";
cBuilder1.QuoteSuffix = "]";

orders_dAdapter.Fill(NW_Orders, "Orders");
order_details_dAdapter.Fill(NW_Orders, "Order Details");

DataColumn parentcolumn = NW_Orders.Tables["Orders"].Columns["Order ID"];
DataColumn childcolumn = NW_Orders.Tables["Order Details"].Columns["Order ID"];
DataRelation relation = new System.Data.DataRelation("OrderstoDetails", parentcolumn, childcolumn);
NW_Orders.Relations.Add(relation);

orders_bndSource = new BindingSource();
orders_bndSource.DataSource = NW_Orders.Tables["Orders"];
order_details_bndSource = new BindingSource();
order_details_bndSource.DataSource = orders_bndSource;
order_details_bndSource.DataMember = "OrderstoDetails";

order_details_bndSource.CurrentItemChanged += new EventHandler(order_details_bndSource_CurrentItemChanged);
order_details_bndSource.ListChanged += new ListChangedEventHandler(order_details_bndSource_ListChanged);

this.textBox1.DataBindings.Add(new Binding("Text", orders_bndSource, "Order ID", true));
this.dateTimePicker1.DataBindings.Add(new Binding("Text", orders_bndSource, "Order Date", true));
this.dateTimePicker2.DataBindings.Add(new Binding("Text", orders_bndSource, "Shipped Date", true));
this.textBox2.DataBindings.Add(new Binding("Text", order_details_bndSource, "ID"));
this.textBox3.DataBindings.Add(new Binding("Text", order_details_bndSource, "Order ID"));
this.textBox4.DataBindings.Add(new Binding("Text", order_details_bndSource, "Quantity"));
this.textBox5.DataBindings.Add(new Binding("Text", order_details_bndSource, "Unit Price"));
this.textBox6.DataBindings.Add(new Binding("Text", order_details_bndSource, "Discount"));
this.textBox7.Text = "" + (order_details_bndSource.Position + 1);
this.textBox8.Text = order_details_bndSource.Count.ToString();

foreach (Control tx in this.Controls) {
if (tx.DataBindings.Count > 0 && tx.Name != "textBox1" && tx.Name != "textBox3") {
tx.Enter += new EventHandler(tx_Enter);
}
}



}

void tx_Enter(object sender, EventArgs e) {
saveprompt = true;
}

void order_details_bndSource_ListChanged(object sender, ListChangedEventArgs e) {
saveprompt = true;
}


private void NextParent_Click(object sender, EventArgs e) {
if (saveprompt) {
DialogResult x = MessageBox.Show("Do you want to save the data first?", "Important", MessageBoxButtons.YesNo);
if (x == DialogResult.Yes) {
try {

orders_bndSource.EndEdit();
order_details_bndSource.EndEdit();
orders_dAdapter.Update(NW_Orders, "Orders");
order_details_dAdapter.Update(NW_Orders, "Order Details");

MessageBox.Show("Record Updated");
}
catch (OleDbException f) {
MessageBox.Show("Record Update Failed - Error Code " + f.ErrorCode.ToString());
}
}
}
orders_bndSource.MoveNext();
this.textBox7.Text = "" + (order_details_bndSource.Position + 1);
this.textBox8.Text = order_details_bndSource.Count.ToString();
saveprompt = false;
}

private void order_details_bndSource_CurrentItemChanged(object sender, EventArgs e) {
saveprompt = true;
}


private void NextChild_Click(object sender, EventArgs e) {
if (saveprompt) {
DialogResult x = MessageBox.Show("Do you want to save the data first?", "Important", MessageBoxButtons.YesNo);
if (x == DialogResult.Yes) {
try {

orders_bndSource.EndEdit();
order_details_bndSource.EndEdit();
orders_dAdapter.Update(NW_Orders, "Orders");
order_details_dAdapter.Update(NW_Orders, "Order Details");

MessageBox.Show("Record Updated");
}
catch (OleDbException f) {
MessageBox.Show("Record Update Failed - Error Code " + f.ErrorCode.ToString());
}
}
}
order_details_bndSource.MoveNext();
this.textBox7.Text = "" + (order_details_bndSource.Position + 1);
saveprompt = false;

}

private void AddNew_Click(object sender, EventArgs e) {
order_details_bndSource.AddNew();

}

private void SaveChanges_Click(object sender, EventArgs e) {
try {

orders_bndSource.EndEdit();
order_details_bndSource.EndEdit();
orders_dAdapter.Update(NW_Orders, "Orders");
order_details_dAdapter.Update(NW_Orders, "Order Details");
saveprompt = false;
MessageBox.Show("Record Updated");
}
catch (OleDbException f) {
MessageBox.Show("Record Update Failed - Error Code " + f.ErrorCode.ToString());
}

}


}
}
308 messaggi dal 08 gennaio 2011
Chiedo scusa, ma bisognerebbe avere un po di buon senso... non si dovrebbe petendere che altri si mettano a leggere codici troppo lunghi....

Ciao.
Modificato da marioformosa il 09 luglio 2012 17.29 -
41 messaggi dal 09 gennaio 2012
No, nessuno chiede di far leggere a video il codice ma di poterlo caricare su VS e rilevare l'anomalia... dopotutto e' un copia e incolla di 2 clic.
Un occhio esperto sa individuare subito dove e' il problema.
308 messaggi dal 08 gennaio 2011
Non direi... in qusto caso un copia/incolla non basta...

Ciao.
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao, scusate, premetto che non ho copiato/incollato nulla :)
Prima di iniziare ad esaminare il codice, verifica dal pannello di esplorazione dei Database di Visual Studio, che i nomi dei campi e delle tabelle siano corretti.

Il database Northwind che ho a portata di mano è quello per Sql Server, ma dovrebbe essere identico a quello di Access. Vedo ad esempio che il campo ID della tabella degli ordini si chiama "OrderID", e non "Order ID" come nel codice fornito. C'è uno spazio di troppo.
La tabella "Order Details" invece è proprio così, con lo spazio.
"UnitPrice" invece è senza spazio.

Controlla bene che tutti i nomi siano corretti.

ciao
Modificato da BrightSoul il 10 luglio 2012 20.33 -

Enjoy learning and just keep making
41 messaggi dal 09 gennaio 2012
grazie mille per la risposta
:-)
... ora ricontrollo tutti i nomi dei campi.

Ma una domanda:
quando il programmillo non trova i nomi dei campi esattamente come li riporto io,non dovrebbe sollevare una eccezione ? e se si come si chiama o come la catturo ?

questa si che e' una rispota che ti aiuta
;-)
saluti
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,

alvaropetro ha scritto:

quando il programmillo non trova i nomi dei campi esattamente come li riporto io,non dovrebbe sollevare una eccezione ?

Sì, spesso è così, infatti prova a recuperare da un DataRow il valore di una colonna che non esiste.
var valore = dataRow["ColonnaInesistente"];
L'istruzione genererà una ArgumentException che puoi catturare con un blocco try...catch.

Tuttavia, come hai sperimentato, esistono casi in cui chi ha progettato il .NET Framework ha scelto di non sollevare eccezioni. E' il caso della collezione Columns del DataTable.
var colonna = dataTable.Columns["ColonnaInesistente"];
Questa riga non produrrà un'eccezione. Alla variabile colonna sarà assegnato il valore null.
Perché questa differenza? Mah... forse perché, parlando di prestazioni, sollevare eccezioni è costoso e quindi, secondo la mia interpretazione, almeno in questo caso hanno preferito evitarlo. Possono esserci anche degli altri motivi di convenienza, ovvio, ma non so quali siano. Io ho l'impressione che ritornare null fosse già sufficiente a far capire allo sviluppatore dell'inesistenza di quella colonna, ma questa è una pratica sconsigliata dalle stesse linee guida.

Per comunicare gli errori, applicazioni e librerie non devono utilizzare codici restituiti.


Nel caso del DataRow, invece, ritornare null avrebbe potuto creare confusione perché questo è un valore valido che puoi assegnare ad una colonna esistente.

Quindi, tornando al tuo problema, può darsi che avendo digitato un nome di colonna inesistente il DataColumn restituito sia null e, tentando di usarlo lo stesso, viene sollevata una NullReferenceException (o più probabilmente una ArgumentException, rileggendo il tuo post iniziale).

ciao
Modificato da BrightSoul il 16 luglio 2012 22.06 -

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.