Il mio progetto a cui sto lavorando è quasi finito. Sto caricando un file .MDB, visualizzando i contenuti su un DataGrid e tentando di ottenere quelle modifiche su DataGrid e salvarle nuovamente nel file .MDB. Creerò anche una funzione che mi consente di prendere le tabelle da un file .MDB e salvarlo in un altro file .MDB. Naturalmente, non posso fare nulla se non riesco a capire come salvare le modifiche nel file .MDB.C# Problema: qual è il modo più semplice per caricare un file .MDB, apportare modifiche e salvare le modifiche sul file originale?
Ho effettuato ricerche approfondite su Google e non ci sono risposte alla mia domanda. Mi considero un principiante su questo argomento specifico quindi per favore non rendere le risposte troppo complicate - Ho bisogno del modo più semplice per modificare un file .MDB! Si prega di fornire esempi di programmazione.
- Si supponga che ho già fatto una connessione a un DataGrid. Come posso ottenere le modifiche apportate da Datagrid? Sono sicuro che questo è abbastanza semplice da rispondere.
- Ho quindi bisogno di sapere come prendere questo Datatable, inserirlo nel Dataset da cui proviene, quindi prendere quel Dataset e riscrivere il file .MDB. (Se c'è un modo di inserire solo i tavoli che sono stati modificati preferirei quello.)
Grazie in anticipo, fammi sapere se hai bisogno di ulteriori informazioni. Questa è l'ultima cosa che probabilmente dovrò chiedere su questo argomento ... grazie a dio.
EDIT:
Il .mdb sto lavorando con un database di di Microsoft Access. (Non sapevo nemmeno che ci fossero più file .mdb)
So che non riesco a scrivere direttamente nel file .MDB tramite uno streamwriter o altro, ma c'è un modo per poter generare un file .MDB con le informazioni del DataSet già in esso? O c'è solo un modo per aggiungere tabelle a un file .MDB che ho già caricato in DataGrid. Ci deve essere un modo!
Anche in questo caso, ho bisogno di un modo per fare questo di programmazione in C#.
EDIT:
Va bene, il mio progetto è abbastanza grande, ma io uso un file di classe separato per gestire tutte le connessioni di database. So che il mio design e la mia fonte sono davvero sciatti, ma il lavoro è fatto. Sono solo buono come gli esempi che trovo su internet.
Ricorda, mi sto semplicemente connettendo a un DataGrid in un altro formato. Fammi sapere se vuoi il mio codice dal modulo Datagrid (non so perché ne avresti bisogno comunque). DatabaseHandling.cs gestisce 2 file .MDB. Quindi vedrai due dataset lì dentro. Lo userò per prendere le tabelle da un set di dati e metterle in un altro dataset. Ho solo bisogno di capire come salvare questi valori INDIETRO in un file .MDB.
Esiste comunque? Ci deve essere un modo ...
EDIT:
da quello che ho studiato e letto ... Penso che la risposta è proprio sotto il mio naso. Utilizzando il comando "Aggiorna()".Ora, mentre questo è rassicurante che c'è un modo semplice per farlo, mi rimane il problema che non ho idea di come usare questo comando di aggiornamento.
Forse posso configurarlo in questo modo:
Oledb.OledbConnection cn = new Oledb.OledbConnection();
cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Staff.mdb";
Oledb.OledbCommand cmd = new Oledb.OledbCommand(cn);
cmd.CommandText = "INSERT INTO Customers (FirstName, LastName) VALUES (@FirstName, @LastName)";
penso che possa farlo, ma non voglio inserire manualmente qualsiasi cosa. Voglio fare entrambe queste invece:
- Prendete le informazioni che è cambiato sul DataGrid e aggiornare il file di database Access (.mdb) che ho preso da
- creare una funzione che mi permette di prendere le tabelle da un altro file di database di Access (.mdb) e sostituirli in un file di database di Access secondario (.mdb). Entrambi i file utilizzeranno la stessa identica struttura ma avranno in essi informazioni diverse.
Spero che qualcuno abbia una risposta per questo ... il mio progetto è fatto, tutto ciò che attende è una semplice risposta.
Grazie ancora in anticipo.
EDIT:
Va bene ... una buona notizia. Ho capito come interrogare il file .mdb stesso (credo). Ecco il codice, che non funziona perché ottengo un errore di runtime a causa del comando sql che sto tentando di utilizzare. Quale mi porterà alla mia prossima domanda.
Nuovo codice funzione aggiunto DatabaseHandling.cs:
static public void performSynchronization(string table, string tableTwoLocation)
{
OleDbCommand cmdCopyTables = new OleDbCommand("INSERT INTO" + table + "SELECT * FROM [MS Access;" + tableTwoLocation + ";].[" + table + "]"); // This query generates runtime error
cmdCopyTables.Connection = dataconnectionA;
dataconnectionA.Open();
cmdCopyTables.ExecuteNonQuery();
dataconnectionA.Close();
}
Come si può vedere, in realtà ho riuscito a eseguire una query sulla connessione in sé, che ritengo essere l'accesso vero e proprio. File MDB. Come ho già detto, la query SQL che ho eseguito sul file non funziona e ha generato un errore di run-time quando utilizzato.
Il comando che sto tentando di eseguire dovrebbe prendere una tabella da un file .MDB e sovrascrivere una tabella dello stesso tipo di un file .MDB differente. Il comando SQL che ho tentato in precedenza ha cercato di prendere direttamente una tabella da un file .mdb, e inserirla direttamente in un'altra - questo non è quello che voglio fare. Voglio prendere tutte le informazioni dal file .MDB - inserire le tabelle in un Datatable e quindi aggiungere tutti i Datatables a un set di dati (cosa che ho fatto.) Voglio farlo per due file .MDB. Una volta che ho due set di dati che vogliono prendere tabelle specifiche di ciascun set di dati e aggiungerli a ciascun file in questo modo:
- DataSetA >>>> ----- [aggiungere tabelle (sovrascriverli)] - ---- >>>> DataSetB
- DataSetB >>>> ----- [aggiungere tabelle (sovrascriverli)] ----- >>>> DataSetA
voglio prendi tutti quei Dataset e poi inseriscili in ciascun file .MDB di Access da cui provengono. Essenzialmente mantenendo entrambi i database sincronizzati.
Così le mie domande, rivisto, è:
- Come si crea una query SQL che aggiungerà una tabella per il file mdb sovrascrivendo quello esistente con lo stesso nome.La query dovrebbe essere in grado di essere creata dinamicamente durante il runtime con una matrice che sostituisce una variabile con il nome della tabella che voglio aggiungere.
- Come posso ottenere le modifiche apportate da Datagrid al DataTable e reinserirle in un DataTable (o DataSet) in modo da poterle inviare al file .MDB?
Ho cercato di elaborare il più possibile ... perché credo di non spiegare molto bene il mio problema. Ora questa domanda è diventata troppo lunga. Spero solo di poterlo spiegare meglio. : [
EDIT:
Grazie ad un utente sotto Credo di aver quasi trovato una soluzione - la parola chiave quasi. Ecco il seguente codice DatabaseHandling.cs aggiornato di seguito. Ottengo un errore di runtime "Datatype Mismatch". Non so come ciò potrebbe essere possibile considerando che sto cercando di copiare queste tabelle in un altro database con la stessa identica configurazione.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;
using System.IO;
namespace LCR_ShepherdStaffupdater_1._0
{
public class DatabaseHandling
{
static DataTable datatableB = new DataTable();
static DataTable datatableA = new DataTable();
public static DataSet datasetA = new DataSet();
public static DataSet datasetB = new DataSet();
static OleDbDataAdapter adapterA = new OleDbDataAdapter();
static OleDbDataAdapter adapterB = new OleDbDataAdapter();
static string connectionstringA = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Settings.getfilelocationA();
static string connectionstringB = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Settings.getfilelocationB();
static OleDbConnection dataconnectionB = new OleDbConnection(connectionstringB);
static OleDbConnection dataconnectionA = new OleDbConnection(connectionstringA);
static DataTable tableListA;
static DataTable tableListB;
static public void addTableA(string table, bool addtoDataSet)
{
dataconnectionA.Open();
datatableA = new DataTable(table);
try
{
OleDbCommand commandselectA = new OleDbCommand("SELECT * FROM [" + table + "]", dataconnectionA);
adapterA.SelectCommand = commandselectA;
adapterA.Fill(datatableA);
}
catch
{
Logging.updateLog("Error: Tried to get " + table + " from DataSetA. Table doesn't exist!");
}
if (addtoDataSet == true)
{
datasetA.Tables.Add(datatableA);
Logging.updateLog("Added DataTableA: " + datatableA.TableName.ToString() + " Successfully!");
}
dataconnectionA.Close();
}
static public void addTableB(string table, bool addtoDataSet)
{
dataconnectionB.Open();
datatableB = new DataTable(table);
try
{
OleDbCommand commandselectB = new OleDbCommand("SELECT * FROM [" + table + "]", dataconnectionB);
adapterB.SelectCommand = commandselectB;
adapterB.Fill(datatableB);
}
catch
{
Logging.updateLog("Error: Tried to get " + table + " from DataSetB. Table doesn't exist!");
}
if (addtoDataSet == true)
{
datasetB.Tables.Add(datatableB);
Logging.updateLog("Added DataTableB: " + datatableB.TableName.ToString() + " Successfully!");
}
dataconnectionB.Close();
}
static public string[] getTablesA(string connectionString)
{
dataconnectionA.Open();
tableListA = dataconnectionA.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });
string[] stringTableListA = new string[tableListA.Rows.Count];
for (int i = 0; i < tableListA.Rows.Count; i++)
{
stringTableListA[i] = tableListA.Rows[i].ItemArray[2].ToString();
}
dataconnectionA.Close();
return stringTableListA;
}
static public string[] getTablesB(string connectionString)
{
dataconnectionB.Open();
tableListB = dataconnectionB.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });
string[] stringTableListB = new string[tableListB.Rows.Count];
for (int i = 0; i < tableListB.Rows.Count; i++)
{
stringTableListB[i] = tableListB.Rows[i].ItemArray[2].ToString();
}
dataconnectionB.Close();
return stringTableListB;
}
static public void createDataSet()
{
string[] tempA = getTablesA(connectionstringA);
string[] tempB = getTablesB(connectionstringB);
int percentage = 0;
int maximum = (tempA.Length + tempB.Length);
Logging.updateNotice("Loading Tables...");
for (int i = 0; i < tempA.Length ; i++)
{
if (!datasetA.Tables.Contains(tempA[i]))
{
addTableA(tempA[i], true);
percentage++;
Logging.loadStatus(percentage, maximum);
}
else
{
datasetA.Tables.Remove(tempA[i]);
addTableA(tempA[i], true);
percentage++;
Logging.loadStatus(percentage, maximum);
}
}
for (int i = 0; i < tempB.Length ; i++)
{
if (!datasetB.Tables.Contains(tempB[i]))
{
addTableB(tempB[i], true);
percentage++;
Logging.loadStatus(percentage, maximum);
}
else
{
datasetB.Tables.Remove(tempB[i]);
addTableB(tempB[i], true);
percentage++;
Logging.loadStatus(percentage, maximum);
}
}
}
static public DataTable getDataTableA()
{
datatableA = datasetA.Tables[Settings.textA];
return datatableA;
}
static public DataTable getDataTableB()
{
datatableB = datasetB.Tables[Settings.textB];
return datatableB;
}
static public DataSet getDataSetA()
{
return datasetA;
}
static public DataSet getDataSetB()
{
return datasetB;
}
static public void InitiateCopyProcessA()
{
DataSet tablesA;
tablesA = DatabaseHandling.getDataSetA();
foreach (DataTable table in tablesA.Tables)
{
CopyTable(table, connectionstringB);
}
}
public static void CopyTable(DataTable table, string connectionStringB)
{
var connectionB = new OleDbConnection(connectionStringB);
foreach (DataRow row in table.Rows)
{
InsertRow(row, table.Columns, table.TableName, connectionB);
}
}
public static void InsertRow(DataRow row, DataColumnCollection columns, string table, OleDbConnection connection)
{
var columnNames = new List<string>();
var values = new List<string>();
for (int i = 0; i < columns.Count; i++)
{
columnNames.Add("[" + columns[i].ColumnName + "]");
values.Add("'" + row[i].ToString().Replace("'", "''") + "'");
}
string sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})",
table,
string.Join(", ", columnNames.ToArray()),
string.Join(", ", values.ToArray())
);
ExecuteNonQuery(sql, connection);
}
public static void ExecuteNonQuery(string sql, OleDbConnection conn)
{
if (conn == null)
throw new ArgumentNullException("conn");
ConnectionState prevState = ConnectionState.Closed;
var command = new OleDbCommand(sql, conn);
try
{
prevState = conn.State;
if (prevState != ConnectionState.Open)
conn.Open();
command.ExecuteNonQuery(); // !!! Runtime-Error: Data type mismatch in criteria expression. !!!
}
finally
{
if (conn.State != ConnectionState.Closed
&& prevState != ConnectionState.Open)
conn.Close();
}
}
}
}
Perché viene visualizzato questo errore? Entrambe le tabelle sono esattamente le stesse. Che cosa sto facendo di sbagliato? Nel peggiore dei casi, come faccio a eliminare la tabella nell'altro file Access .MDB prima di inserire la stessa tabella di struttura con valori diversi all'interno?
Uomo Vorrei poter solo questo numero ...
EDIT:
Va bene, sono venuto una certa distanza. La mia domanda si è trasformata in una nuova, e quindi merita di essere chiesta separatamente. Ho avuto risposta alla mia domanda poiché ora so come eseguire query direttamente sulla connessione che ho aperto. Grazie a tutti!
@Remou: cercando di ottenere la vostra attenzione qui - si stanno facendo peggiorare la situazione. L'accesso! = MDB. Tutte queste domande che stai taggando da MDB a MS-ACCESS non comportano affatto l'accesso, ma solo il motore di database Jet/ACE. Sto taggando di conseguenza. –
@Remou @David W. Fenton: ho sollevato questo problema su meta: http://meta.stackoverflow.com/questions/33216/ms-access-or-mdb-or-access-database-engine-or- ms-jet-ase – onedaywhen
Ho già pubblicato su Meta. MDB eguaglia anche i bean basati sui messaggi, quindi è un tag ambiguo e, come Access, che è etichettato come ms-access a causa di ambiguità, deve essere modificato. – Fionnuala