C# Aggiornamento DataSet

venerdì 23 ottobre 2009 - 08.49

Franto Profilo | Junior Member

Ciao a tutti, ho il seguente problema.
Ho una form con un datagrid e vorrei gestire l'estrazione/aggiornamento dati in una classe apposta.
nel momento in cui effettuo la ricerca per l'estrazione dei dati, faccio una chiamata alla mia classe DBClass in questo modo:

vcDBClass.DBRead("soggetti", "SELECT * FROM SOGGETTI", out vcDataSet);
gridControl1.DataSource = vcDataSet.Tables[0];

dove vcDBClass e vcDataSet sono dichiarate a livello di componente, ecco la funzione DBRead:

public void DBRead(string pTableName,string pReadCondition, out DataSet pDataSet)
{
string vConnectionString = ConfigurationSettings.AppSettings["connectionString"].ToString();
OdbcConnection vConnection = new OdbcConnection(vConnectionString);

OdbcCommand vCommand = vConnection.CreateCommand();
DataSet vDataSet = new DataSet();

vConnection.Open();
vCommand.CommandText = pReadCondition;

OdbcDataAdapter vcAdapter = new OdbcDataAdapter(vCommand);
vcAdapter.Fill(vDataSet);
vConnection.Close();
pDataSet = vDataSet;
}
Fin qui tutto ok.
Quando vado a modificare i dati a video sul datagrid, cerco di memorizzare in questo modo:

vcDBClass.DBUpdate(vcDataSet, out vcStatus);
if (vcStatus == false) MessageBox.Show("Errore in salvataggio soggetti");

ecco la DBUpdate:

public void DBUpdate(DataSet pDataset, out bool pStatus)
{
try
{
vcAdapter.Update(pDataset);
pDataset.AcceptChanges();
pStatus = true;
}
catch
{
pStatus = false;
}
}

La parte dell'aggiornamento, non funziona...sapete dirmi cosa sbaglio???
Grazie!!
--------------------------------------------------------------
Il destino è solo una giustificazione a ciò che è accaduto, che accade e che accadrà. Apriamo gli occhi e riprendiamoci la nostra vita.

ysdemarc Profilo | Expert

credo che hai dimenticato a dire al dataAdapter che i dati del DataTable possono essere soggetti a modifiche.

prova a cambaire la routine di estrazione così:
public void DBRead(string pTableName,string pReadCondition, out DataSet pDataSet) { string vConnectionString = ConfigurationSettings.AppSettings["connectionString"].ToString(); OdbcConnection vConnection = new OdbcConnection(vConnectionString); OdbcCommand vCommand = vConnection.CreateCommand(); DataSet vDataSet = new DataSet(); vConnection.Open(); vCommand.CommandText = pReadCondition; OdbcDataAdapter vcAdapter = new OdbcDataAdapter(); //-- le seguenti servono solo in caso è possibile l'aggiornamento -- OdbcCommandBuilder cb = new OdbcCommandBuilder(vcAdapter); cb.RefreshSchema(); //------------------------------------------------------------------ vcAdapter.SelectCommand = vCommand; //-- le seguenti servono solo in caso è possibile l'aggiornamento -- vcAdapter.DeleteCommand = cb.GetDeleteCommand(); vcAdapter.InsertCommand = cb.GetInsertCommand(); vcAdapter.UpdateCommand = cb.GetUpdateCommand(); //------------------------------------------------------------------ vcAdapter.Fill(vDataSet); vConnection.Close(); pDataSet = vDataSet; }

Vincenzo
Programmatore sbilenco

Franto Profilo | Junior Member

Ciao Vincenzo, grazie x aver risposto.
Ho provato a modificare la routine di estrazione, ma nel momento in cui vado ad effettuare l'update con vcAdapter.Update(pDataset); , mi restituisce il seguente errore:
- Nel caso di update :
"Update requires a valid UpdateCommand when passed DataRow collection with modified rows."
- Nel caso di insert :
"Update requires a valid InsertCommand when passed DataRow collection with new rows."

e così via..
Ora, sono sempre e comunque costretto a passare un SQL di UPDATE/INSERT/... per fare l'aggiornamento del db?
--------------------------------------------------------------
Il destino è solo una giustificazione a ciò che è accaduto, che accade e che accadrà. Apriamo gli occhi e riprendiamoci la nostra vita.

ysdemarc Profilo | Expert

veramente avevo dato per buono che l'estrazione funzionasse.. forse il problema è dovuto alla connessione.

da un sunto di una mia classettina, funzionante, ti ho rimodificato il codice come segue:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

a dirti il vero la mia classe lavora con le intefacce di System.Data e a seconda la stringa di connessione sa se deve usare gli oggetti di System.Data.SqlClient, using System.Data.Odbc o System.Data.OleDb, mentre non riesco a farla funzionare con Oracle..

comunque posso assicurarti che con gli oggetti di SqlClient e OleDb funziona..con Odbc non l'ho mai testata, quindi potrebbe esserci qualche piccolo errore.. tipo nell'SqlClient mi si è reso necessario inserire queste righe:
cb.RefreshSchema(); cb.QuotePrefix ="["; cb.QuoteSuffix = "]";

prova le routine così modificate e vedi se funzionano.

ciao
Vincenzo
Programmatore sbilenco

Franto Profilo | Junior Member

Ciao!! Funziona!!
Grazie 1000.
Posto il codice finale così se può servire a qualcuno......allora:

Premessa: le variabili con prefisso vc* sono variabili dichiarate a livello di componente
Form1 :
vcDataSet = vcDBClass.DBRead("SELECT * FROM SOGGETTI");
gridControl1.DataSource = vcDataSet.Tables[0];
Classe:
public DataSet DBRead(string pReadCondition)
{
//se la connessione è chiusa la apre
if (vcConnection.State == ConnectionState.Closed) vcConnection.Open();

OdbcCommand vCommand = new OdbcCommand(pReadCondition, (OdbcConnection)vcConnection);
vcAdapter.SelectCommand = vCommand;

//-- le seguenti servono solo in caso è possibile l'aggiornamento --
OdbcCommandBuilder cb = new OdbcCommandBuilder(vcAdapter);
cb.RefreshSchema();

vcAdapter.DeleteCommand = cb.GetDeleteCommand();
vcAdapter.InsertCommand = cb.GetInsertCommand();
vcAdapter.UpdateCommand = cb.GetUpdateCommand();
//------------------------------------------------------------------

DataSet vDataSet = new DataSet();
try
{
vcAdapter.Fill(vDataSet);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
//chide la connessione ma non metto a null
vcConnection.Close();
}
return vDataSet;
}

Mentre x l'aggiornamento:
Form1:
vcDBClass.DBUpdate(vcDataSet, out vcStatus);
if (vcStatus == false) MessageBox.Show("Errore in salvataggio soggetti");
Classe:
public int DBUpdate(DataSet pDataset, out bool pStatus)
{
int rowInserted = 0;
int rowUpdated = 0;
int rowDeleted = 0;
pStatus = true;

DataTable dt = pDataset.Tables[0];
try
{
rowInserted = vcAdapter.Update(dt.Select(null, null, DataViewRowState.Added));
rowUpdated = vcAdapter.Update(dt.Select(null, null, DataViewRowState.ModifiedCurrent));
rowDeleted = vcAdapter.Update(dt.Select(null, null, DataViewRowState.Deleted));

pDataset.AcceptChanges();
}
catch (Exception e)
{
pDataset.RejectChanges();
pStatus = false;
}
finally
{
vcConnection.Close();
}

return rowInserted + rowUpdated + rowDeleted;
}

E questo è tutto.
Grazie ancora!


--------------------------------------------------------------
Il destino è solo una giustificazione a ciò che è accaduto, che accade e che accadrà. Apriamo gli occhi e riprendiamoci la nostra vita.

ysdemarc Profilo | Expert

>Ciao!! Funziona!!
>Grazie 1000.

mi fa piacere..di nulla..

effettivamente ho visto che avevo sbagliato a scrivere qualche nome di variabile

ciao

Vincenzo
Programmatore sbilenco

Franto Profilo | Junior Member

Ciao, mi trovo costretto a riaprire il thread perché, per motivi di lavoro, ho dovuto spostare i miei controlli da MySQL a dBASE.
Con dBASE è sorto un problema sull'aggiornamento di record esistenti.

Il codice inserito per consentire l'aggiornamento della tabella, non funziona più.
Ossia, quando vado a fare la vcAdapter.DeleteCommand = cb.GetDeleteCommand(), il compilatore mi ritorna questo messaggio:
"Dynamic SQL generation for the DeleteCommand is not supported against a SelectCommand that does not return any key column information."

Avete soluzioni in merito?


--------------------------------------------------------------
Il destino è solo una giustificazione a ciò che è accaduto, che accade e che accadrà. Apriamo gli occhi e riprendiamoci la nostra vita.

ysdemarc Profilo | Expert

sicuramente nella select hai dimenticato di mettere le colonne chiavi della tua tabella. e quindi non riesce a capire che riche deve cancellare non avendo anche l'estrazione delle chiavi.

ciao
Vincenzo
Programmatore sbilenco

Franto Profilo | Junior Member

La select è SELECT * FROM TABGEN.

Ho notato che riesce a recuperare la INSERT.
La DELETE e l'UPDATE, niente da fare.

--------------------------------------------------------------
Il destino è solo una giustificazione a ciò che è accaduto, che accade e che accadrà. Apriamo gli occhi e riprendiamoci la nostra vita.

ysdemarc Profilo | Expert

allora la tabella non ha chiavi definite. verifica
Vincenzo
Programmatore sbilenco

Franto Profilo | Junior Member

Ciao, le tabelle in dBASE non credo accettino la definizione di una chiave.
Si possono tuttavia creare degli indici e lì definire le chiavi univoche.

Non vorrei dire cavolate, ma mi sembra di aver capito così.

Dovrei trovere penso un modo di accedere agli indici delle tabelle.


--------------------------------------------------------------
Il destino è solo una giustificazione a ciò che è accaduto, che accade e che accadrà. Apriamo gli occhi e riprendiamoci la nostra vita.

ysdemarc Profilo | Expert

se nella select non ci sono informazioni di indici o chiavi per .net è impossibile capire cosa vuoi cancellare o aggiornare

a meno che non usi le istruzioni di UPDATE e DELETE direttamente da query..e quindi senza utilizzare l'oggetto datatable che hai ottenuta dalla select
Vincenzo
Programmatore sbilenco
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5