Мой проект, над которым я работаю, почти завершен. Я загружаю файл .MDB, отображаю содержимое в DataGrid и пытаюсь получить эти изменения в DataGrid и сохранить их обратно в файл .MDB. Я также собираюсь создать функцию, которая позволит мне взять таблицы из одного файла .MDB и сохранить его в другом файле .MDB. Конечно, я не могу ничего сделать, если не могу понять, как сохранить изменения обратно в файл .MDB.
Я тщательно исследовал Google, и на мой вопрос нет ответов. Я считаю себя новичком в этой конкретной теме, поэтому, пожалуйста, не усложняйте ответы - мне нужен самый простой способ отредактировать файл .MDB! Пожалуйста, предоставьте примеры программирования.
- Предположим, что я уже установил соединение с DataGrid. Как я могу получить изменения, сделанные Datagrid? Я уверен, что этот вопрос достаточно прост, чтобы ответить.
- Затем мне нужно знать, как взять этот набор данных, вставить его в набор данных, из которого он получен, затем взять этот набор данных и переписать файл .MDB. (Если есть способ только вставить таблицы, которые были изменены, я бы предпочел это.)
Заранее спасибо, дайте мне знать, если вам нужна дополнительная информация. Это последнее, что мне, вероятно, придется спросить об этой теме ... слава богу.
EDIT:
.mdb, с которой я работаю, это База данных Microsoft Access. (я даже не знал, что было несколько файлов .mdb)
Я знаю, что не могу записать напрямую в файл .MDB через потоковую запись или что-то еще, но есть ли способ, которым я могу сгенерировать файл .MDB с уже имеющейся информацией DataSet? ИЛИ есть ли способ добавить таблицы в файл .MDB, который я уже загрузил в DataGrid. Должен быть способ!
Опять же, мне нужен способ сделать это ПРОГРАММНО в C #.
EDIT:
Хорошо, мой проект довольно большой, но я использую отдельный файл класса для обработки всех соединений с БД. Я знаю, что мой дизайн и источник действительно неаккуратный, но он выполняет свою работу. Я так же хорош, как примеры, которые я нахожу в Интернете.
Помните, я просто подключаюсь к DataGrid в другой форме. Дайте мне знать, если вам нужен мой код из формы Datagrid (хотя я не знаю, зачем он вам понадобится). DatabaseHandling.cs обрабатывает 2 файла .MDB. Таким образом, вы увидите два набора данных там. Я буду использовать это в конечном итоге, чтобы взять таблицы из одного набора данных и поместить их в другой набор данных. Мне просто нужно выяснить, как сохранить эти значения НАЗАД в файл .MDB.
Есть ли в любом случае, чтобы сделать это? Должен быть способ ...
EDIT:
Из того, что я исследовал и прочитал ... Я думаю, что ответ прямо у меня под носом. С помощью команды «Обновить ()». Теперь, когда это подтверждает, что существует простой способ сделать это, я все еще остаюсь с проблемой, что у меня нет никакой подсказки, как использовать эту команду обновления.
Возможно, я смогу настроить это так:
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)";
Я думаю, что это может сделать, но я не хочу вставлять что-либо вручную. Я хочу сделать оба из них вместо:
- Возьмите информацию, которая изменена в Datagrid, и обновите файл базы данных Access (.mdb), который я получил от
- Создайте функцию, которая позволит мне брать таблицы из другого файла базы данных Access (.mdb) и заменять их во вторичном файле базы данных Access (.mdb). Оба файла будут использовать одну и ту же структуру, но в них будет разная информация.
Я надеюсь, что кто-то придумает ответ на этот вопрос ... мой проект завершен, все, что ждет, - это один простой ответ.
Заранее еще раз спасибо.
EDIT:
Хорошо ... хорошие новости. Я выяснил, как запросить сам файл .mdb (я думаю). Вот код, который не работает, потому что я получаю ошибку во время выполнения из-за команды sql, которую я пытаюсь использовать. Что приведет меня к следующему вопросу.
Добавлен новый код функции в 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();
}
Как видите, мне действительно удалось выполнить запрос к самому соединению, которое, как я считаю, является действительным файлом Access .MDB. Как я уже сказал, SQL-запрос, который я выполнил для файла, не работает и выдает ошибку во время выполнения.
Команда, которую я пытаюсь выполнить, должна взять таблицу из файла .MDB и перезаписать таблицу того же типа, что и другой файл .MDB. Команда SQL, которую я пытался описать выше, пыталась напрямую взять таблицу из файла .mdb и напрямую поместить ее в другой файл - это не то, что я хочу сделать. Я хочу взять всю информацию из файла .MDB - поместить таблицы в Datatable, а затем добавить все Datatables в набор данных (что я и сделал). Я хочу сделать это для двух файлов .MDB. После того, как у меня есть два набора данных, я хочу взять определенные таблицы из каждого набора данных и добавить их в каждый файл следующим образом:
- DataSetA >>>> ----- [Добавить таблицы
(Перезаписать их)] ----- >>>> DataSetB
- DataSetB >>>> ----- [Добавить таблицы
(Перезаписать их)] ----- >>>> DataSetA
Я хочу взять каждый из этих наборов данных и затем поместить их НАЗАД в каждый файл Access .MDB, из которого они пришли. По сути, синхронизация обеих баз данных.
Итак, мои вопросы, пересмотренные, таковы:
- Как создать запрос SQL, который добавит таблицу в файл .MDB, перезаписав существующую с тем же именем. Запрос должен иметь возможность динамически создаваться во время выполнения с помощью массива, который заменяет переменную именем таблицы, которую я хочу добавить.
- Как получить изменения, сделанные Datagrid, в DataTable и поместить их обратно в DataTable (или DataSet), чтобы я мог отправить их в файл .MDB?
Я пытался уточнить как можно больше ... потому что я считаю, что я не очень хорошо объясняю свою проблему. Теперь этот вопрос стал слишком длинным. Я просто хотел бы объяснить это лучше. : [
EDIT:
Спасибо пользователю ниже, я думаю, что я почти нашел исправление - ключевое слово почти .
Вот мой обновленный код DatabaseHandling.cs ниже. Я получаю ошибку времени выполнения "Несоответствие типов данных". Я не знаю, как это возможно, учитывая, что я пытаюсь скопировать эти таблицы в другую базу данных с точно такой же настройкой.
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();
}
}
}
}
Почему я получаю эту ошибку? Обе таблицы абсолютно одинаковы. Что я делаю неправильно?
В худшем случае, как мне удалить таблицу в другом файле Access .MDB перед тем, как вставить точно такую же таблицу структуры с другими значениями в ней?
Чувак, я бы хотел это выяснить ...
EDIT:
Хорошо, я прошел некоторое расстояние. Мой вопрос превратился в новый, и поэтому заслуживает отдельного обсуждения. Мне ответили на мой вопрос, так как теперь я знаю, как выполнять запросы непосредственно к открытому соединению. Спасибо всем!