gpt4 book ai didi

C# Issue : What is the simplest way for me to load a . MDB 文件,对其进行更改,并将更改保存回原始文件?

转载 作者:行者123 更新时间:2023-12-02 01:53:18 25 4
gpt4 key购买 nike

我正在做的项目快要完成了。我正在加载一个 .MDB 文件,在 DataGrid 上显示内容并尝试在 DataGrid 上获取这些更改并将它们保存回 .MDB 文件。我还将创建一个函数,该函数允许我从一个 .MDB 文件中获取表并将其保存到另一个 .MDB 文件中。当然,如果我无法弄清楚如何将更改保存回 .MDB 文件,我将无法执行任何操作。

我对谷歌进行了广泛的研究,但我的问题没有答案。我认为自己是这个特定主题的初学者,所以请不要让答案太复杂——我需要最简单的方法来编辑 .MDB 文件!请提供编程示例。

  • 假设我已经连接到 DataGrid。如何获取 Datagrid 所做的更改?我相信这个很简单,可以回答。
  • 然后我需要知道如何获取这个数据表,将它插入它来自的数据集,然后获取该数据集并重写 .MDB 文件。 (如果有一种方法可以只插入已更改的表,我更愿意这样做。)

  • 预先感谢您,如果您需要更多信息,请告诉我。关于这个话题,这是我可能要问的最后一件事……谢天谢地。

    编辑:

    我正在使用的 .mdb 是 微软访问数据库。 (我什至不知道有多个 .mdb 文件)

    我知道我不能通过流写入器或任何东西直接写入 .MDB 文件,但是有没有办法可以生成一个 .MDB 文件,其中已经包含了 DataSet 信息?或者只有一种方法可以将表添加到我已经加载到 DataGrid 中的 .MDB 文件中。必须有办法!

    同样,我需要一种方法来做到这一点 以编程方式 在 C# 中。

    编辑:

    好的,我的项目相当大,但我使用单独的类文件来处理所有数据库连接。我知道我的设计和来源真的很草率,但它完成了工作。我只和我在互联网上找到的例子一样好。

    请记住,我只是以另一种形式连接到 DataGrid。如果您想要我的 Datagrid 表单代码,请告诉我(我不知道您为什么需要它)。 DatabaseHandling.cs 处理 2 个 .MDB 文件。所以你会在那里看到两个数据集。我最终将使用它从一个数据集中取出表并将它们放入另一个数据集中。我只需要弄清楚如何将这些值保存到 .MDB 文件中。

    有没有办法做到这一点?必须有办法...

    编辑:

    从我研究和阅读的内容来看......我认为答案就在我的眼皮底下。使用“Update()”命令。现在,虽然这再次确保实际上有一种简单的方法可以做到这一点,但我仍然有一个问题,即我不知道如何使用此更新命令。

    也许我可以这样设置:
    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)。这两个文件将使用完全相同的结构,但其中包含不同的信息。

  • 我希望有人想出一个答案……我的项目已经完成,等待的只是一个简单的答案。

    再次感谢您。

    编辑:

    好吧……好消息。我已经想出了如何查询 .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 文件中获取所有信息 - 将表放入数据表中,然后将所有数据表添加到数据集(我已经完成)。我想对两个 .MDB 文件执行此操作。一旦我有两个数据集,我想从每个数据集中取出特定的表并将它们添加到每个文件中,如下所示:
  • DataSetA >>>>----- [添加表
    (覆盖它们)] ----->>>> DataSetB
  • DataSetB >>>>----- [添加表
    (覆盖它们)] ----->>>> DataSetA

  • 我想将这些数据集分别取出,然后将它们放回它们来自的每个 Access .MDB 文件中。基本上保持两个数据库同步。

    所以我的问题,修改后,是:
  • 如何创建一个 SQL 查询,通过覆盖现有的同名表将表添加到 .MDB 文件中。查询应该能够在运行时动态创建,使用一个数组替换我想要添加的表名的变量。
  • 如何获取 Datagrid 对 DataTable 所做的更改并将它们放回 DataTable(或 DataSet)中,以便我可以将它们发送到 .MDB 文件?

  • 我已经尽量详细说明了……因为我相信我没有很好地解释我的问题。现在这个问题已经变得太长了。我只是希望我能更好地解释这一点。 :[

    编辑:

    感谢下面的用户,我想我几乎找到了解决方法——关键字几乎。
    下面是我更新的 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 文件中的表?

    伙计,我希望我能弄清楚这一点......

    编辑:

    好吧,我已经走了一段距离。我的问题变成了一个新问题,因此值得单独提出。我已经回答了我的问题,因为现在我知道如何直接对我打开的连接执行查询。谢谢你们!

    最佳答案

    我不确定你已经走了多远,但如果你正在寻找快速拖放操作,你可能想看看创建一个连接的强类型数据集,并使用数据源工具窗口的拖放功能在 Visual Studio 中。

    那里肯定有样本,但你会想要的。

  • 创建一个新的数据集
  • 从服务器资源管理器中的数据连接树拖放
  • 创建新表单
  • 从数据源工具中拖动表格
  • 窗体上的窗口。

  • 更新:

    首先,我不是 100% 理解你的问题。如果您可以在最好的访问文件之间创建一些 LinkTables,那么您可以使用诸如“INSERT INTO Customers SELECT FirstName, LastName FROM File2.Customers”之类的 sql 语句在文件之间复制数据。如果不是这样,我认为您将不得不循环数据表并使用类似于上次编辑的 INSERT 语句手动插入记录。至于数据网格,您可能必须通过监视 RowChanged 事件(不确定这是否是确切事件)来跟踪更改的内容,甚至在行更改时执行插入/更新语句。

    更新:

    循环数据表你会做这样的事情。未测试。我刚刚再次更新它以包含 MakeValueDbReady 函数。这也没有经过测试,我不确定我是否正确处理了所有案例甚至所有案例。您真的必须调试 sql 语句并确保其生成正确的值。每个数据库处理不同的值。至少以这种方式提取值解析。我还意识到,不是对 TableName 进行硬编码,您应该能够从 DataTable 上的属性中获取它
    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>();

    // generate the column and value names from the datacolumns
    for(int i =0;i<columns.Count; i++)
    {
    columnNames.Add("[" + columns[i].ColumnName + "]");
    // datatype mismatch should be fixed by this function
    values.Add(MakeValueDbReady(row[i], columns[i].DataType));
    }

    // create the sql
    string sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})",
    table,
    string.Join(", ", columnNames.ToArray()),
    string.Join(", ", values.ToArray())
    );

    // debug the accuracy of the sql here and even copy into
    // a new Query in Access to test
    ExecuteNonQuery(sql, connection);
    }

    // as the name says we are going to check the datatype and format the value
    // in the sql string based on the type that the database is expecting
    public string MakeValueDbReady(object value, Type dataType)
    {
    if (value == null)
    return null;

    if (dataType == typeof(string))
    {
    return "'" + value.ToString().Replace("'", "''") + "'"
    }
    else if (dataType == typeof(DateTime))
    {
    return "#" + ((DateTime)value).ToString + "#"
    }
    else if (dataType == typeof(bool))
    {
    return ((bool)value) ? "1" : "0";
    }

    return value.ToString();
    }

    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
    {
    // the reason we are checking the prev state is for performance reasons
    // later you might want to open the connection once for the a batch
    // of say 500 rows or even wrap your connection in a transaction.
    // we don't want to open and close 500 connections
    prevState = conn.State;
    if (prevState != ConnectionState.Open)
    conn.Open();

    command.ExecuteNonQuery();
    }
    finally
    {
    if (conn.State != ConnectionState.Closed
    && prevState != ConnectionState.Open)
    conn.Close();
    }
    }

    关于C# Issue : What is the simplest way for me to load a . MDB 文件,对其进行更改,并将更改保存回原始文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/518239/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com