Sqlite - Bulk Insert

  • C#
  • .NET (FX) 1.0–2.0

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Sqlite - Bulk Insert

    Hallo,
    ich versuche gerade eine Menge Datensätze in eine SQLite Datenbank zu schreiben. Nach etwas suche im Web bin ich auf die möglichkeit gestossen den Insert-Prozess mit "Bulk Insert" wesentlich zu beschleunigen.

    Leider durchläuft meine foreach-Schleife nicht alle Einträge sondndern nur 2 und ich finde den Fehler nicht. Liegt es an der Schleife selbst oder am umgeschriebenen Code mit Bulk.
    Kann mir mal jemand einen Tip geben, finde leider nicht heraus warum die Schleife nicht bis zum Ende läuft.

    C#-Quellcode

    1. void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    2. {
    3. //Durchlaufe das Verzeichniss und finde alle Audiodatein
    4. var allfiles = System.IO.Directory.GetFiles(Dirpath,
    5. "*.*",
    6. System.IO.SearchOption.AllDirectories).Where(
    7. s => s.EndsWith(".mp3") ||
    8. s.EndsWith(".wav") ||
    9. s.EndsWith(".wma") ||
    10. s.EndsWith(".flac") ||
    11. s.EndsWith(".ape"));
    12. using (var connection = new SQLiteConnection(@"Data Source = musikdb.db"))
    13. {
    14. connection.Open();
    15. using (var command = new SQLiteCommand(connection))
    16. {
    17. using (var transaction = connection.BeginTransaction())
    18. {
    19. int i = 0;
    20. foreach (string file in allfiles)
    21. {
    22. i++;
    23. try
    24. {
    25. TagLib.File soundfile = TagLib.File.Create(file);
    26. string[] filename_vor_split = file.Split('\\');
    27. string filename = filename_vor_split[filename_vor_split.Length - 1];
    28. string title = soundfile.Tag.Title;
    29. string[] artist = soundfile.Tag.Performers;
    30. string album = soundfile.Tag.Album;
    31. string tracknr = soundfile.Tag.TrackCount.ToString();
    32. string year = soundfile.Tag.Year.ToString();
    33. string genre = soundfile.Tag.TitleSort;
    34. command.Parameters.AddWithValue("@filename", filename);
    35. command.Parameters.AddWithValue("@title", title);
    36. command.Parameters.AddWithValue("@artist", artist);
    37. command.Parameters.AddWithValue("@album", album);
    38. command.Parameters.AddWithValue("@track", tracknr);
    39. command.Parameters.AddWithValue("@year", year);
    40. command.Parameters.AddWithValue("@genre", genre);
    41. command.Parameters.AddWithValue("@pfad", file);
    42. command.CommandText = String.Format(
    43. "INSERT INTO title (filename, title, artist, album, track, year, genre, pfad) VALUES (@filename, @title, @artist, @album, @track, @year, @genre, @pfad)");
    44. command.ExecuteNonQuery();
    45. int percentage = (i + 1) * 100 / anzahl;
    46. // Report progress to 'UI' thread
    47. backgroundWorker1.ReportProgress(i);
    48. }
    49. catch (Exception)
    50. {
    51. }
    52. transaction.Commit();
    53. }
    54. }
    55. connection.Close();
    56. }
    57. }
    58. MessageBox.Show("Fertig. Es wurden alle Titel importiert.");
    59. }
    Soweit ich weiß, musst du zuerst den Command Text erstellen und dann erst die Daten per AddWithValue reinpacken. Schiebt einfach mal Zeilen 47 bis 49 vor Zeile 38
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Habe den Fehler schon gefunden. Es lag daran das ich ​transaction.Commit() in die foreach-Schleife gepackt habe.
    Damit habe ich die Zeit fürs eintragen der Daten von 17 Sek. auf 2 Sek. reduzieren können.

    Habe den Try Block weil nicht alle Audiodateien auch Metadaten haben und dann das Programm abstürtzt. Das das keine gute Lösung ist weiß ich, hatte es aber erstmal so geschrieben und will später den Teil des Codes umschreiben.
    @ErfinderDesRades Ich bin grad dabei anstelle des großen Try-Blocks eine vernünftige Fehlerbehandlung zu schreiben.

    Ich hänge gerade aber fest. Mit folgendem Code lese ich aus der Audiodatei den Artisten aus:

    C#-Quellcode

    1. string[] artist = soundfile.Tag.Performers;

    Natürlich ist nicht bei allen Dateien der Tag hinterlegt und deswegen bekomm ich eine OutOfRange Meldung.

    Wie kann ich das am besten behandeln, komme leider nicht zurecht.
    echt - eine IndexOutOfRange - Meldung?
    Kann eiglich nicht sein. In der Zeile wird ja gar kein Index verwendet,
    Oder die Bibliothek ist ziemlich mangelhaft.

    Wie du das behandelst, musst du doch konzipieren, das kann ich dir doch nicht sagen, wie du das haben willst.
    Ich würde evtl. die Datei in einen gesonderten Ordner verschieben.
    Evtl würde ich acuh garnix machen - wenn die Datei keinen Performer-Tag eingetragen hat, dann hat sie halt ein Performer.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ja, das ist klar aber ich wusste nicht genau wie ich das am besten mache.
    Habe jetzt aber nach etwas suche im Netz die Funktion Array.Resize gefunden und sobald kein Tag hinterlegt ist und das Array somit leer ist, lege ich eine neue Größe fest und schreibe einen eigenen String hinein.

    Trotzdem danke :).