Как я могу сохранить DataTable в .DBF? - PullRequest
3 голосов
/ 27 ноября 2008

Я работал над программой для чтения файла dbf, работы с данными и сохранения его обратно в dbf. Проблема, с которой я столкнулся, связана именно с частью письма.

    private const string constring = "Driver={Microsoft dBASE Driver (*.dbf)};"
                                   + "SourceType=DBF;"
                                   + "DriverID=277;"
                                   + "Data Source=¿;"
                                   + "Extended Properties=dBASE IV;";
    private const string qrystring = "SELECT * FROM [¿]";
    public static DataTable loadDBF(string location)
    {
        string filename = ConvertLongPathToShort(Path.GetFileName(location));
        DataTable table = new DataTable();
        using(OdbcConnection conn = new OdbcConnection(RTN(constring, filename)))
        {
            conn.Open();
            table.Load(new OdbcCommand(RTN(qrystring, filename), conn).ExecuteReader());
            conn.Close();
        }
        return table;
    }

    private static string RTN(string stmt, string tablename)
    { return stmt.Replace("¿", tablename); }

    [DllImport("Kernel32", CharSet = CharSet.Auto)]
    static extern Int32 GetShortPathName(
    String path,                // input string
    StringBuilder shortPath,    // output string
    Int32 shortPathLength);     // StringBuilder.Capacity

    public static string ConvertLongPathToShort(string longPathName)
    {
        StringBuilder shortNameBuffer;
        int size;

        shortNameBuffer = new StringBuilder();

        size = GetShortPathName(longPathName, shortNameBuffer, shortNameBuffer.Capacity);
        if (size >= shortNameBuffer.Capacity)
        {
            shortNameBuffer.Capacity = size + 1;
            GetShortPathName(longPathName, shortNameBuffer, shortNameBuffer.Capacity);
        }

        return shortNameBuffer.ToString();
    }

Это то, с чем я работаю. Я попробовал несколько методов, чтобы написать новый файл, но ни один из них не был продуктивным. Честно говоря, в то время как обычно я был бы сторонником формы и функции, я просто хочу, чтобы эта чертова штука сработала, это приложение должно делать одну очень специфическую вещь, оно не будет имитировать погоду.

- = # Edit # = -

С тех пор я прекратил приложение из-за нехватки времени, но перед тем, как отменить его, я понял, что в конкретном формате dbf, с которым я работал, не было информации первичного ключа. Это, конечно, означало, что мне пришлось по существу считывать данные в DataTable, связываться с ними, а затем стирать все записи в dbf и вставлять все с нуля. Винт это для жаворонка.

Ответы [ 3 ]

5 голосов
/ 29 июля 2013

Для людей, приезжающих сюда в будущем: я написал это сегодня, и это работает хорошо. Имя файла без расширения (.dbf). Путь (используется для подключения) - это только путь к каталогу (без файла). Вы можете добавить свои данные в набор данных и передать их. Кроме того, некоторые из моих типов данных относятся к типам данных foxpro и могут быть несовместимы со всеми файлами DBF. Надеюсь, это поможет.

    public static void DataSetIntoDBF(string fileName, DataSet dataSet)
    {
        ArrayList list = new ArrayList();

        if (File.Exists(Path + fileName + ".dbf"))
        {
            File.Delete(Path + fileName + ".dbf");
        }

        string createSql = "create table " + fileName + " (";

        foreach (DataColumn dc in dataSet.Tables[0].Columns)
        {
            string fieldName = dc.ColumnName;

            string type = dc.DataType.ToString();

            switch (type)
            {
                case "System.String":
                    type = "varchar(100)";
                    break;

                case "System.Boolean":
                    type = "varchar(10)";
                    break;

                case "System.Int32":
                    type = "int";
                    break;

                case "System.Double":
                    type = "Double";
                    break;

                case "System.DateTime":
                    type = "TimeStamp";
                    break;
            }

            createSql = createSql + "[" + fieldName + "]" + " " + type + ",";

            list.Add(fieldName);
        }

        createSql = createSql.Substring(0, createSql.Length - 1) + ")";

        OleDbConnection con = new OleDbConnection(GetConnection(Path));

        OleDbCommand cmd = new OleDbCommand();

        cmd.Connection = con;

        con.Open();

        cmd.CommandText = createSql;

        cmd.ExecuteNonQuery();

        foreach (DataRow row in dataSet.Tables[0].Rows)
        {
            string insertSql = "insert into " + fileName + " values(";

            for (int i = 0; i < list.Count; i++)
            {
                insertSql = insertSql + "'" + ReplaceEscape(row[list[i].ToString()].ToString()) + "',";
            }

            insertSql = insertSql.Substring(0, insertSql.Length - 1) + ")";

            cmd.CommandText = insertSql;

            cmd.ExecuteNonQuery();
        }

        con.Close();
    }

    private static string GetConnection(string path)
    {
        return "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + ";Extended Properties=dBASE IV;";
    }

    public static string ReplaceEscape(string str)
    {
        str = str.Replace("'", "''");
        return str;
    }
2 голосов
/ 10 февраля 2009

Использование ADO.Net для чтения и записи dbf-файлов оказывается очень медленным, поэтому я бы предложил вам использовать альтернативный подход.

Один из вариантов - использовать старую библиотеку DAO 3.6. Это намного быстрее и одинаково совместимо, но зависит от объекта com для работы.

Лучше было бы использовать открытый компонент DBFExporter, компонент . Это может потребовать некоторого кода для настройки (вам нужен класс со свойствами, которые описывают ваш набор записей, а свойства должны иметь определенные атрибуты), но после этого он работает действительно хорошо. Это быстро использовать, но он не читает файлы DBF. Компонент имеет лицензии LGPL, поэтому вы можете использовать его в коммерческом коде.

1 голос
/ 28 ноября 2008

С каким файлом dbf вы работаете? (Некоторые из них, например, dBase, FoxPro и т. Д., Не совместимы на 100%.) Я получил это для работы с провайдером Microsoft Visual FoxPro OleDB из C #, вы могли бы сделать это вместо использования драйвера ODBC dBase.

...