Мой проект, над которым я работаю, почти закончен. Я загружаю файл .MDB, отображая содержимое в DataGrid и пытаясь получить эти изменения в DataGrid и сохраняя их обратно в файл .MDB. Я также собираюсь создать функцию, которая позволяет мне принимать таблицы из одного файла .MDB и сохранять его в другом .MDB-файле. Конечно, я не могу ничего сделать, если не могу понять, как сохранить изменения обратно в файл .MDB.Проблема с C#: Какой самый простой способ загрузить файл .MDB, внести в него изменения и сохранить изменения в исходный файл?
Я внимательно изучил Google, и на мой вопрос нет ответов. Я считаю себя новичком в этой конкретной теме, поэтому, пожалуйста, не делайте ответы слишком сложными - мне нужен самый простой способ редактировать файл .MDB! Просьба представить примеры программирования.
- Предположим, что я уже подключился к DataGrid. Как получить изменения, внесенные Datagrid? Я уверен, что это достаточно просто, чтобы ответить.
- Мне тогда нужно знать, как взять этот Datatable, вставить его в набор данных, откуда он пришел, затем взять этот набор данных и переписать файл .MDB. (Если есть способ только вставить таблицы, которые были изменены, я бы предпочел это.)
Спасибо заранее, дайте мне знать, если вам нужна дополнительная информация. Это последнее, что мне, вероятно, придется спросить об этой теме ... слава богу.
EDIT:
.mdb Я работаю с базой данных является Microsoft Access. (я даже не знал, что было несколько файлов .mdb)
Я знаю, что не могу писать непосредственно в файл .MDB через потоковик или что-то еще, но есть способ, которым я могу сгенерировать файл .MDB с информацией DataSet уже в нем? ИЛИ есть только способ, которым я могу добавить таблицы в файл .MDB, который уже загружен в DataGrid. Там должен быть путь!
Опять же, мне нужен способ, чтобы сделать это в C# Программным способом.
EDIT:
Хорошо, мой проект достаточно велик, но я использую отдельный файл класса для обработки всех соединений с базами данных. Я знаю, что мой дизайн и источник действительно неряшливы, но он выполняет свою работу. Я так же хорош, как примеры, которые я нахожу в Интернете.
Помните, что я просто подключаюсь к DataGrid в другой форме. Дайте мне знать, если вы хотите, чтобы мой код из формы Datagrid (я не знаю, зачем вам это нужно). DatabaseHandling.cs обрабатывает файлы 2.MDB. Таким образом, вы увидите два набора данных. Я буду использовать это в конечном счете, чтобы взять таблицы из одного набора Данных и поместить их в другой Набор данных. Мне просто нужно выяснить, как сохранить эти значения BACK в .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 File (MDB), который я получил его от
- Создайте функцию, которая позволяет мне брать таблицы из другого файла базы данных доступа (.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();
}
Как вы можете видеть, я на самом деле удалось выполнить запрос на само соединение, которое я считаю, что фактический доступ. 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 ниже. Я получаю ошибку времени выполнения "Datatype Mismatch." Я не знаю, как это возможно, учитывая, что я пытаюсь скопировать эти таблицы в другую базу данных с той же самой настройкой.
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, прежде чем вставлять в нее ту же самую таблицу структуры с разными значениями?
Man Я хотел бы просто понять это ...
EDIT:
Хорошо, я пришел на некоторое расстояние. Мой вопрос превратился в новый, и поэтому заслуживает того, чтобы его спросили отдельно. На мой вопрос был ответ, так как теперь я знаю, как выполнять запросы непосредственно к открытому мне соединению. Спасибо вам всем!
@Remou: пытается привлечь ваше внимание здесь - вы делаете плохую ситуацию хуже. Доступ! = MDB. Все эти вопросы, которые вы перемаркируете с MDB на MS-ACCESS, не связаны с доступом вообще, а только с механизмом базы данных Jet/ACE. Я перемаркирован соответствующим образом. –
@Remou @David W. Fenton: Я поднял эту проблему на мета: http://meta.stackoverflow.com/questions/33216/ms-access-or-mdb-or-access-database-engine-or- ms-jet-ace – onedaywhen
Я уже размещен на Meta. MDB также равен Message-Driven Beans, поэтому он является двусмысленным тегом и, подобно Access, который помечен как ms-access из-за неоднозначности, нуждается в изменении. – Fionnuala