C# المسألة:ما هو أبسط طريقة لتحميل .ملف MDB, إجراء تغييرات عليه, و حفظ التغييرات مرة أخرى إلى الملف الأصلي?

StackOverflow https://stackoverflow.com/questions/518239

سؤال

مشروعي الذي أعمل على الانتهاء تقريبا.أنا تحميل .ملف MDB, عرض محتويات على DataGrid و محاولة الحصول على تلك التغييرات على DataGrid وحفظها مرة أخرى إلى .ملف MDB.أنا أيضا ذاهب إلى إنشاء وظيفة تسمح لي أن آخذ الجداول من واحد .ملف MDB وحفظه إلى آخر .ملف MDB.بالطبع أنا لا يمكن أن تفعل أي شيء من هذا إذا كنت لا يمكن معرفة كيفية حفظ التغييرات مرة أخرى إلى .ملف MDB.

لقد بحثت في جوجل على نطاق واسع وهناك لا يجيب على سؤالي.أنا أعتبر نفسي مبتدئا في هذا الموضوع لذا يرجى لا تجعل إجابات معقدة جدا-أنا في حاجة إلى أبسط طريقة تحرير .ملف MDB!يرجى تقديم أمثلة البرمجة.

  1. نفترض أن كنت قد قدمت بالفعل اتصال DataGrid.كيف يمكنني الحصول على التغييرات التي أجراها Datagrid?ايم متأكد من أن هذا هو واحد بسيط بما فيه الكفاية للإجابة.
  2. ثم تحتاج إلى معرفة كيفية اتخاذ هذا Datatable ، أدخله Dataset جاء من ثم تنقل هذه البيانات و كتابة .ملف MDB.(إذا كان هناك وسيلة فقط إدراج الجداول التي تم تغييرها كنت تفضل ذلك.)

شكرا لكم مقدما, اسمحوا لي أن أعرف إذا كنت بحاجة إلى مزيد من المعلومات.هذا هو آخر شيء أنا ربما يجب أن نسأل عن هذا الموضوع...الحمد لله.

تحرير:

على .mdb أنا أعمل مع هو بيانات Microsoft Access. ( لم أكن أعرف حتى كان هناك متعددة .ملفات mdb)

وأنا أعلم أنني لا يمكن الكتابة مباشرة .ملف MDB عبر streamwriter أو أي شيء ولكن هل هناك طريقة ما يمكن أن ولدت .ملف MDB مع بيانات المعلومات بالفعل في ذلك ؟ أو هل هناك طريقة يمكنني إضافة جداول إلى .MDB الملفات التي سبق تحميلها في DataGrid.يجب أن يكون هناك طريقة!

مرة أخرى أريد طريقة للقيام بذلك برمجيا في C#.

تحرير:

إن المشروع هو كبير الى حد ما ولكن يمكنني استخدام منفصلة ملف فئة للتعامل مع جميع اتصالات قاعدة البيانات.أنا أعرف بلدي تصميم و المصدر هو حقا قذرة ، ولكن فإنه يحصل على هذه المهمة.أنا فقط جيدة مثل الأمثلة يمكنني العثور على شبكة الإنترنت.

تذكر, أنا ببساطة الاتصال DataGrid في شكل آخر.اسمحوا لي أن أعرف إذا كنت تريد قانون بلدي من Datagrid شكل (أنا لا أعرف لماذا كنت في حاجة إليها على الرغم من).DatabaseHandling.cs مقابض 2 .ملفات MDB.لذلك سوف نرى اثنين من مجموعات البيانات هناك.وسوف تستخدم هذه في نهاية المطاف إلى اتخاذ الجداول من قاعدة البيانات ووضعها في آخر Dataset.أنا فقط بحاجة إلى معرفة كيفية حفظ هذه القيم مرة أخرى إلى .ملف MDB.

هناك على أية حال أن تفعل هذا ؟ يجب أن يكون هناك طريقة...

تحرير:

من ما كنت بحثت وقراءة...أعتقد أن الجواب هو الحق تحت الأنف.استخدام "تحديث()" الأمر.الآن في حين أن هذا هو إعادة مؤكدا أن هناك في الواقع طريقة بسيطة للقيام بذلك ، أنا مع المشكلة التي لدي لا friggin-فكرة عن كيفية استخدام هذا التحديث الأوامر.

ربما أنا يمكن أن يحدد مثل هذا:

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 File (.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();
}

كما يمكنك أن ترى في الواقع لقد تمكنت من تنفيذ استعلام على اتصال نفسها التي أعتقد أن الوصول الفعلي .ملف MDB.كما قلت على الرغم من استعلام SQL لقد أعدم على الملف لا يعمل و إنشاء خطأ وقت التشغيل عند استخدامها.

الأمر أنا محاولة تنفيذ يفترض أن يأخذ جدول من قاعدة .MDB ملف الكتابة فوق الجدول من نفس نوع مختلف .ملف MDB.أمر SQL حاولت أعلاه حاولت أن تأخذ مباشرة من الجدول a .ملف mdb و وضعه مباشرة في آخر هذا ليس ما أريد القيام به.أريد أن تأخذ جميع المعلومات من .ملف MDB-وضع الجداول في Datatable ثم إضافة كافة Datatables إلى Dataset (الذي قمت به.) أريد أن أفعل هذا لمدة سنتين .ملفات MDB.مرة واحدة لدي اثنين من مجموعات البيانات أريد أن جداول محددة من كل مجموعة البيانات وإضافتها إلى كل ملف مثل هذا:

  • DataSetA >>>>----- [إضافة الجداول (الكتابة عليها)] ----->>>> DataSetB
  • DataSetB >>>>----- [إضافة الجداول (الكتابة عليها)] ----->>>> DataSetA

أريد أن تأخذ تلك كل تلك البيانات ومن ثم وضعها مرة أخرى في كل الوصول .ملف MDB أتوا.أساسا حفظ كل قواعد البيانات متزامنة.

لذا أسئلتي ، المنقحة،:

  1. كيف يمكنني إنشاء استعلام SQL التي من شأنها إضافة جدول .ملف MDB طريق الكتابة الموجودة من نفس الاسم.الاستعلام يجب أن يكون قادرا على أن يكون إنشاؤها بشكل حيوي أثناء وقت التشغيل مع مجموعة أن يستبدل متغير مع اسم الجدول أريد أن أضيف.
  2. كيف يمكنني الحصول على التغييرات التي تم إجراؤها من قبل Datagrid إلى DataTable ووضعها مرة أخرى إلى DataTable (أو البيانات) حتى أستطيع أن أرسل لهم .MDB ملف ؟

لقد حاولت وضع قدر الإمكان لأنني أعتقد أنني لم أوضح قضية بلدي بشكل جيد جدا.الآن هذا السؤال نمت wayyy طويلة جدا.أتمنى فقط أن يفسر هذا أفضل.:[

تحرير:

بفضل المستخدم أدناه أعتقد أنني قد وجدت ما يقرب من إصلاح -- الكلمة الرئيسية تقريبا.هنا هو بلدي تحديث 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();
                }
            }

            }          
        }

لماذا أنا على هذا الخطأ ؟ كل الجداول هي نفسها بالضبط.ما الخطأ الذي فعلته ؟ أسوأ الأحوال, كيف يمكنني حذف الجدول في الوصول الأخرى .ملف MDB قبل إدخال نفس هيكل الجدول مع قيم مختلفة في ذلك ؟

رجل أتمنى لو أستطيع معرفة ذلك...

تحرير:

حسنا, لقد أتيت بعض المسافة.سؤالي قد تحولت إلى واحدة جديدة ، وبالتالي يستحق أن يطلب منه بشكل منفصل.لقد كان سؤالي فأجاب الآن أعرف كيفية تنفيذ الاستعلامات مباشرة إلى اتصال قد فتحت.شكرا لكم جميعا!

هل كانت مفيدة؟

المحلول

لست متأكدا إلى أي مدى وصلت, ولكن إذا كنت تبحث عن وسيلة سريعة قم بسحب وإسقاط العملية قد ترغب في النظر في إنشاء كتابة بشدة dataset الذي يربط باستخدام السحب والإسقاط الميزات من DataSources أداة نافذة في Visual Studio.

هناك بالتأكيد عينات هناك, ولكن سوف تحتاج إلى.

  1. إنشاء new DataSet
  2. السحب والإسقاط من DataConnection شجرة في "مستكشف الملقم"
  3. إنشاء نموذج جديد
  4. اسحب الجدول من DataSources أداة
  5. نافذة على شكل.
  6. فويلا

تحديث:

أولا: أنا لست 100% أن أفهم هذه المسألة.إذا كنت يمكن أن تخلق بعض LinkTables بين الوصول إلى الملفات التي من شأنها أن تكون أفضل, ثم يمكنك نسخ البيانات بين الملفات باستخدام sql مثل 'INSERT INTO العملاء حدد الاسم الأول اسم العائلة من File2.العملاء'.إذا كان هذا لا خيار أعتقد أن الذهاب إلى حلقة DataTables و إدراج السجلات يدويا باستخدام إدراج بيانات مماثلة إلى آخر تحرير.أما بالنسبة datagrid ، ربما سيكون لديك لتتبع ما تغير من خلال رصد RowChanged الحدث (لست متأكدا إذا كان هذا الحدث المحدد) حتى لا إدراج/تحديث البيانات عند الصف التغييرات.

تحديث:

حلقة datatable كنت تفعل شيئا من هذا القبيل.لم تختبر.لقد قمت بتحديث هذا مرة أخرى تشمل 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();
    }
}

نصائح أخرى

تحديث ملف MDB الأصلي مع التغييرات التي أدخلت على DataSet (لا DataGrid ، لأن هذا هو فقط واجهة المستخدم على بيانات) فقط استخدام DataAdapter.التحديث الأوامر.

إلى نقل الجداول من 1 إلى أخرى هو أصعب قليلا.إذا كان الجدول لا موجودة بالفعل في الوجهة, سوف تحتاج إلى إنشاء باستخدام SQL إنشاء بيان.ثم ، DataAdapter.ملء DataSet من المصدر.حلقة من خلال كل صف وتعيين الدولة RowAdded عن طريق الاتصال DataRow.SetAdded.ثم تمر عليه إلى DataAdapter.التحديث من الوجهة قاعدة البيانات.

تحرير: رمز على السؤال التالي....

هناك في الواقع أكثر من واحد شكل ملف .mdb التمديد.لذا ، إذا اعتقد خطأ واحد ، وستكون هذه إجابة خاطئة.ولكن يبدو أن Microsoft Access المسألة.

أنت لا تكتب مباشرة إلى ملف MDB.فهي مشفرة ومضغوطة.أسهل طريقة تعديل ملف MDB هو تحميله من خلال الوصول إلى نسخ الجداول من خلال أساليب المقدمة.

كيف يمكنك الاتصال إلى قاعدة البيانات (ملف .ملف mdb)?يمكنك إضافة بعض التعليمات البرمجية?إذا كنت متصلا بشكل صحيح من أي عمليات SQL ضدك يجب أن يتم حفظها في قاعدة البيانات تلقائيا.

حتى بعد الاتصال إلى قاعدة البيانات يمكنك تنفيذ SQL التي سيتم إنشاء الجداول إدراج/تحديث/استرداد البيانات ، إلخ.محاولة بناء .ملف mdb باليد ليس من المستحسن.

هنا مثال:

http://www.java2s.com/Code/CSharp/Database-ADO.net/Access.htm

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top