C # SQLite импорт файлов предотвращает дублирование - PullRequest
0 голосов
/ 26 мая 2010

Я пытаюсь получить каталог (который постоянно растет), полный файлов с разделителями-запятыми .txt для импорта в мою базу данных SQLite. Теперь у меня есть все импортируемые файлы, но мне нужно каким-то образом исключить файлы, которые были ранее добавлены в БД. У меня есть столбец в БД с именем FileName, где имя и расширение хранятся рядом с каждой записью из каждого файла. Теперь мне нужно сказать: «Если код находит XXX.txt и XXX.txt уже находится в БД, пропустите этот файл». Можно ли как-то добавить эту логику в команду getfiles или есть другой простой способ?

using (SQLiteCommand insertCommand = con.CreateCommand())
                {
                    SQLiteCommand cmdd = con.CreateCommand();
                    string[] files = Directory.GetFiles(@"C:\Documents and Settings\js91162\Desktop\", "R303717*.txt*", SearchOption.AllDirectories);
                    foreach (string file in files)
                    {

                        string FileNameExt1 = Path.GetFileName(file);



                        cmdd.CommandText =
                            @" 
                    SELECT COUNT(*) FROM Import WHERE FileName = @FileExt;";
                        cmdd.Parameters.Add(new SQLiteParameter("@FileExt", FileNameExt1));

                    int count = Convert.ToInt32(cmdd.ExecuteScalar());
                    //int count = ((IConvertible)insertCommand.ExecuteScalar().ToInt32(null));

                    if (count == 0)
                    {

                        Console.WriteLine("Parsing CMM data for SQL database... Please wait.");

                        insertCommand.CommandText =
                            @" 
                    INSERT INTO Import  (FeatType, FeatName, Value, Actual, Nominal, Dev, TolMin, TolPlus, OutOfTol, PartNumber, CMMNumber, Date, FileName) 
                    VALUES     (@FeatType, @FeatName, @Value, @Actual, @Nominal, @Dev, @TolMin, @TolPlus, @OutOfTol, @PartNumber, @CMMNumber, @Date, @FileName);";

                        insertCommand.Parameters.Add(new SQLiteParameter("@FeatType", DbType.String));
                        insertCommand.Parameters.Add(new SQLiteParameter("@FeatName", DbType.String));
                        insertCommand.Parameters.Add(new SQLiteParameter("@Value", DbType.String));
                        insertCommand.Parameters.Add(new SQLiteParameter("@Actual", DbType.Decimal));
                        insertCommand.Parameters.Add(new SQLiteParameter("@Nominal", DbType.Decimal));
                        insertCommand.Parameters.Add(new SQLiteParameter("@Dev", DbType.Decimal));
                        insertCommand.Parameters.Add(new SQLiteParameter("@TolMin", DbType.Decimal));
                        insertCommand.Parameters.Add(new SQLiteParameter("@TolPlus", DbType.Decimal));
                        insertCommand.Parameters.Add(new SQLiteParameter("@OutOfTol", DbType.Decimal));
                        insertCommand.Parameters.Add(new SQLiteParameter("@Comment", DbType.String));




                        string FileNameExt = Path.GetFileName(file);
                        string RNumber = Path.GetFileNameWithoutExtension(file);

                        string RNumberE = RNumber.Split('_')[0];

                        string RNumberD = RNumber.Split('_')[1];
                        string RNumberDate = RNumber.Split('_')[2];

                        DateTime dateTime = DateTime.ParseExact(RNumberDate, "yyyyMMdd", Thread.CurrentThread.CurrentCulture);
                        string cmmDate = dateTime.ToString("dd-MMM-yyyy");
                        string[] lines = File.ReadAllLines(file);
                        bool parse = false;

                        foreach (string tmpLine in lines)
                        {


                            string line = tmpLine.Trim();
                            if (!parse && line.StartsWith("Feat. Type,"))
                            {
                                parse = true;
                                continue;
                            }
                            if (!parse || string.IsNullOrEmpty(line))
                            {
                                continue;
                            }

                            Console.WriteLine(tmpLine);
                            foreach (SQLiteParameter parameter in insertCommand.Parameters)
                            {
                                parameter.Value = null;
                            }

                            string[] values = line.Split(new[] { ',' });

                            for (int i = 0; i < values.Length - 1; i++)
                            {
                                SQLiteParameter param = insertCommand.Parameters[i];
                                if (param.DbType == DbType.Decimal)
                                {
                                    decimal value;
                                    param.Value = decimal.TryParse(values[i], out value) ? value : 0;
                                }
                                else
                                {
                                    param.Value = values[i];
                                }
                            }
                            insertCommand.Parameters.Add(new SQLiteParameter("@PartNumber", RNumberE));
                            insertCommand.Parameters.Add(new SQLiteParameter("@CMMNumber", RNumberD));
                            insertCommand.Parameters.Add(new SQLiteParameter("@Date", cmmDate));
                            insertCommand.Parameters.Add(new SQLiteParameter("@FileName", FileNameExt));
                            // 
                            insertCommand.ExecuteNonQuery();

                        }


                    } 
                    }
                    Console.WriteLine("CMM data successfully imported to SQL database...");
                } 
                con.Close(); 
            } 

РЕДАКТИРОВАТЬ. Возможно, если есть способ сказать, если (файл 'присутствует в db') {} ???

Ответы [ 3 ]

1 голос
/ 26 мая 2010

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

foreach (string file in directoryFilenames.Except(databaseFilenames))
{
   // do something
}

Бен Робинсон предлагает аналогичный ответ, но использование Where и Contains будет повторять второй список для каждого элемента в первом списке. Метод Except будет повторять второй список только один раз.

0 голосов
/ 26 мая 2010

Сделайте столбец имени файла уникальным или добавьте уникальный индекс для него, а затем выполните INSERT OR IGNORE, в результате чего дубликаты будут игнорироваться без выброса исключений.

0 голосов
/ 26 мая 2010

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

Редактировать: Ваш обновленный код сделает свое дело, но он будет работать все дольше и дольше, поскольку ваш каталог заполняется, потому что вы запрашиваете базу данных для каждого файла в каталоге. Если бы вы могли получить список импортированных файлов из базы данных в List<string>, вы могли бы затем сделать следующее, используя linq:

List<string> ImportedFiles = GetImportedFileList() // Method that gets the list of files from the db
foreach (string file in files.Where(fl => !ImportedFiles.Contains(fl)))

Это будет означать, что ваш цикл foreach будет перебирать только те файлы, которых еще нет в базе данных.

Я предполагал, что вы знаете, как написать метод GetImportedFileList(), который получает список файлов из БД и возвращает их как List<string>.

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