У меня есть файл CSV со следующей структурой в качестве примера одной строки: 01.01.2020;12:00:00;50;100;150
У меня есть файл базы данных SQLite с таблицей со следующей структурой столбцов: DateAndTime as TEXT, Field1 as INTEGER, Field2 as INTEGER, Field3 as INTEGER, AddField as INTEGER (THAT field depends from UserInput and is not from CSV)
(у меня нет выбора объявить DateAndTime как DATETIME в моей базе данных Sqlite.)
Прежде всего, я думаю, что я не могу сделать это с массовой вставкой, потому что мне нужно преобразовать некоторые значения в нужный объект (первый и второй столбец CSV в ОДНОМ объекте datetime, добавьте последний параметр из UserInput). Другие значения CSV в порядке, они простые целые числа.
Кроме того, мне нужно проверить, вставлено ли уже введенное мной значение. Если да, игнорируйте эту строку и переходите к следующей строке.
Шаги, которые я сделал до сих пор:
List<MyObject> MyObjectList = new List<MyObject>();
using (StreamReader file = new StreamReader(@filepath))
{
string ln;
while ((ln = file.ReadLine()) != null)
{
if (!String.IsNullOrWhiteSpace(ln))
{
try
{
string[] ValuesStringArray = ln.Split(';');
string[] DateArray = ValuesStringArray[0].Split('.');
string[] TimeArray = ValuesStringArray[1].Split(':');
DateTime dateTime = new DateTime(Int16.Parse(DateArray[2]),
Int16.Parse(DateArray[1]),
Int16.Parse(DateArray[0]),
Int16.Parse(TimeArray[0]),
Int16.Parse(TimeArray[1]),
Int16.Parse(TimeArray[2]));
int field1 = Int32.Parse(ValuesStringArray[2]);
int field2 = Int32.Parse(ValuesStringArray[3]);
int field3 = Int32.Parse(ValuesStringArray[4]);
int addField = Int32.Parse(USERINPUT blabla);
MyObject myObject = new MyObject() {DateTime = dateTime, Field1 = field1, Field2 = field2, Field3 = field3, AddField = addField };
MyObjectList.Add(myObject);
........
Затем я перебираю MyObjectList и вставляю его в базу данных с помощью следующих операторов :
INSERT INTO MyTable (DateTime, Field1, Field2, Field3, AddField) SELECT @DateTime, @Field1, @Field2, @Field3, @AddField WHERE NOT EXISTS (SELECT 1 FROM MyTable WHERE DateTime = @DateTime AND Field1 = @Field1 AND [..so on]);
@statements получают параметры и находятся в транзакции, поэтому для всех вставок это одна транзакция.
Моя проблема в том, что эта процедура займет много времени, когда CSV-файл имеет длину 100 000 строк. Время одной вставки увеличивается экспоненциально. Первая вставка занимает от 0 до 1 мс, что будет немного увеличиваться по мере продолжения вставки. Я согласен с первой частью кода с созданием MyObjectList и его заполнением, это работает очень хорошо и быстро для меня.
Мне нужна ваша помощь, чтобы получить транзакцию вставки как можно быстрее. Есть ли лучший способ поиска дубликатов и игнорировать, когда есть один? Любые советы или примеры будут полезны.