Заполнение таблицы базы данных SQLite из файла CSV - PullRequest
0 голосов
/ 18 февраля 2020

Я изо всех сил пытаюсь заставить мой код работать.

Я комбинирую примеры, которые я нашел здесь: Разбор CSV с использованием OleDb с использованием C# и Сохранить набор данных в файл формата SQLite

Я читаю файл CSV в DataSet, используя OleDbConnection и OleDbDataAdapter (который работает), а затем сохраняю этот DataSet в базу данных SQLite, используя SQLiteConnection и SQLiteDataAdapter (который не работает).

Тестовый код из 2-го примера выше работает просто отлично, где DataSet создается из кода и затем сохраняется в базе данных.

MasterDataTable в базе данных уже существует , Я создал его непосредственно в целевой базе данных.

Вот мой код:

using System;
using System.Data;
using System.Data.OleDb;
using System.Data.SQLite;
using System.IO;

namespace DataAdapterExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a simple dataset
            DataTable table = new DataTable("MasterDataTable");
            DataSet ds = new DataSet();
            ds.Tables.Add(table);
            var filename = @"C:\Users\willi\Downloads\MasterDataReport2.csv";
            var connString = string.Format(
                @"Provider=Microsoft.Jet.OleDb.4.0; 
                Data Source={0};
                Extended Properties=""Text;
                HDR=YES;
                FMT=Delimited""", 
                Path.GetDirectoryName(filename));
            using (var conn = new OleDbConnection(connString))
            {
                conn.Open();
                var query = "SELECT * FROM [" + Path.GetFileName(filename) + "]";
                using (var adaptr = new OleDbDataAdapter(query,conn))
                {
                    adaptr.Fill(table);
                }
            }
            // Save in an SQLite file
            string desktopPath =
                Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            string fullPath = desktopPath + "\\class.db";
            SQLiteConnection con = new SQLiteConnection("Data Source=" + fullPath);
            con.Open();
            // Create a table in the database to receive the information from the DataSet
            SQLiteCommand cmd = new SQLiteCommand(con);
            SQLiteDataAdapter adaptor = new SQLiteDataAdapter("SELECT * from MasterDataTable", con);
            adaptor.InsertCommand = new SQLiteCommand("INSERT INTO MasterDataTable VALUES (" +
                ":startTime, " +
                ":entryId, " +
                ":entryType, " +
                ":category, " +
                ":class, " +
                ":participants, " +
                ":studioName, " +
                ":routineTitle)",
                con
            );
            adaptor.InsertCommand.Parameters.Add("startTime", DbType.String, 0, "StartTime");
            adaptor.InsertCommand.Parameters.Add("entryId", DbType.Int16, 0, "EntryID");
            adaptor.InsertCommand.Parameters.Add("entryType", DbType.String, 0, "EntryType");
            adaptor.InsertCommand.Parameters.Add("category", DbType.String, 0, "Category");
            adaptor.InsertCommand.Parameters.Add("class", DbType.String, 0, "Class");
            adaptor.InsertCommand.Parameters.Add("participants", DbType.String, 0, "Participants");
            adaptor.InsertCommand.Parameters.Add("studioName", DbType.String, 0, "StudioName");
            adaptor.InsertCommand.Parameters.Add("routineTitle", DbType.String, 0, "Routine Title");
            adaptor.Update(ds, "MasterDataTable");
            //Check database by filling the dataset in the other direction and displaying
            ds = new DataSet();
            adaptor.Fill(ds, "MasterDataTable");
            foreach (DataTable dt in ds.Tables)
            {
                Console.WriteLine("Table {0}", dt.TableName);
                foreach (DataRow dr in dt.Rows)
                {
                    foreach (DataColumn dc in dt.Columns)
                    {
                        Console.Write("{0,-18}", dr[dc]);
                    }
                    Console.WriteLine();
                }
            }
        }
    }
}

Любая помощь будет высоко ценится.

1 Ответ

0 голосов
/ 18 февраля 2020

Я нашел причину и решение.

Причина заключалась в том, что строки добавляются в DataSet из OleDbDataAdapter.Fill () с состоянием «Неизменен». Метод SQLiteDataAdapter.Update () считывает «неизмененный» RowState и не выполняет запрос INSERT.

Мое решение было поставить:

foreach (DataRow row in ds.Tables[0].Rows)
{
   row.SetAdded();
}

после вызова Fill () для установите для RowState каждой строки значение «Added».

Окончательное рабочее решение:

using System;
using System.Data;
using System.Data.OleDb;
using System.Data.SQLite;
using System.IO;

namespace DataAdapterExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a simple dataset
            DataSet ds = new DataSet();
            var filename = @"C:\Users\willi\Downloads\MasterDataReport2.csv";
            var connString = string.Format(
                @"Provider=Microsoft.Jet.OleDb.4.0; 
                Data Source={0};
                Extended Properties=""Text;
                HDR=YES;
                FMT=Delimited""", 
                Path.GetDirectoryName(filename));
            using (var conn = new OleDbConnection(connString))
            {
                conn.Open();
                var query = "SELECT * FROM [" + Path.GetFileName(filename) + "]";
                using (var adaptr = new OleDbDataAdapter(query,conn))
                {
                    adaptr.Fill(ds);
                }
            }

            // Change the RowState to "Added" for the Update() method
            foreach (DataRow row in ds.Tables[0].Rows)
            {
                row.SetAdded();
            }

            // Save in an SQLite file
            string desktopPath =
                Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            string fullPath = desktopPath + "\\class.db";
            SQLiteConnection con = new SQLiteConnection("Data Source=" + fullPath);
            con.Open();
            // receive the information from the DataSet into the db
            SQLiteCommand cmd = new SQLiteCommand(con);
            SQLiteDataAdapter adaptor = new SQLiteDataAdapter("SELECT * from MasterDataTable", con);
            adaptor.InsertCommand = new SQLiteCommand("INSERT INTO MasterDataTable VALUES (" +
                ":startTime, " +
                ":entryId, " +
                ":entryType, " +
                ":category, " +
                ":class, " +
                ":participants, " +
                ":studioName, " +
                ":routineTitle)",
                con
            );
            adaptor.InsertCommand.Parameters.Add("startTime", DbType.String, 0, "StartTime");
            adaptor.InsertCommand.Parameters.Add("entryId", DbType.Int16, 0, "EntryID");
            adaptor.InsertCommand.Parameters.Add("entryType", DbType.String, 0, "EntryType");
            adaptor.InsertCommand.Parameters.Add("category", DbType.String, 0, "Category");
            adaptor.InsertCommand.Parameters.Add("class", DbType.String, 0, "Class");
            adaptor.InsertCommand.Parameters.Add("participants", DbType.String, 0, "Participants");
            adaptor.InsertCommand.Parameters.Add("studioName", DbType.String, 0, "StudioName");
            adaptor.InsertCommand.Parameters.Add("routineTitle", DbType.String, 0, "Routine Title");
            adaptor.Update(ds);
            //Check database by filling the dataset in the other direction and displaying
            ds = new DataSet();
            adaptor.Fill(ds);
            foreach (DataTable dt in ds.Tables)
            {
                Console.WriteLine("Table {0}", dt.TableName);
                foreach (DataRow dr in dt.Rows)
                {
                    foreach (DataColumn dc in dt.Columns)
                    {
                        Console.Write("{0,-18}", dr[dc]);
                    }
                    Console.WriteLine();
                }
            }
        }
    }
}

Этот код является всего лишь рабочим прототипом для более крупного проекта, но он работает, как и ожидалось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...