Ошибка цикла вставки SQLite «SQLiteException:« база данных заблокирована » - PullRequest
0 голосов
/ 17 мая 2019

Я пытаюсь вставить DataTable в таблицу SQLite, и для этого я использую цикл foreach, но выдает ошибку SQLiteException: 'database is locked.

Я попытался найти это в Google и попытаться избавиться от моего соединения с using

Вот мой код

public void Insert_to_db(DataTable data)
{
   foreach (DataRow row in data.Rows)
   {
           string alertTag = row["Alert Tag"].ToString();
           int group = Convert.ToInt32(row["Group"]);
           int line = Convert.ToInt32(row["Line"]);
           int task = Convert.ToInt32(row["Task"]);

           string sql = string.Format("insert into alert_tag (alert_tag, layer_group, line, task) values ('{0}','{1}','{2}','{3}')", alertTag, group, line, task);

           using (SQLiteConnection dbConn = new SQLiteConnection(Tools.SqliteConnString()))
           {
               using (SQLiteCommand command = new SQLiteCommand(sql, dbConn))
               {
                   dbConn.Open();
                   command.ExecuteNonQuery();
                   dbConn.Close();
               }
           }
   }
}

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

Итак, как предложил @JhonB, я остановился на использовании dapper, но сначала мне нужно преобразовать мой DataTabe в список объектов

private List<AlertTagModel> convert(DataTable dt)
{
   var convertedData = (from rw in dt.AsEnumerable()
                        select new AlertTagModel() {
                            alert_tag = Convert.ToString(rw["AlertTag"]),
                            layer_group = Convert.ToInt32(rw["Group"]),
                            line = Convert.ToInt32(rw["Line"]),
                            task = Convert.ToInt32(rw["Task"])
                            }).ToList();
   return convertedData;
}

, а затем вставить в БД с помощью dapper

public void Insert_to_db(Object data)
{
     using (IDbConnection cnn = new SQLiteConnection(Tools.LoadConnectionString()))
     {
          cnn.Execute("insert into alert_tag (AlertTag, Layer_ID, Line_ID, Task_ID) values (@alert_tag, @layer_group, @line, @task)", data);
     }
}

Решено!

0 голосов
/ 17 мая 2019

Вам нужно изменить код так, чтобы зацикливание происходило внутри using dbConn:

    using (SQLiteConnection dbConn = new SQLiteConnection(Tools.SqliteConnString()))
    {
        using (SQLiteCommand command = new SQLiteCommand(sql, dbConn))
        {
            dbConn.Open();

            string alertTag;
            int group;
            int line;
            int task;
            string sql;

            foreach (DataRow row in data.Rows)
            {
                alertTag = row["Alert Tag"].ToString();
                group = Convert.ToInt32(row["Group"]);
                line = Convert.ToInt32(row["Line"]);
                task = Convert.ToInt32(row["Task"]);
                sql = string.Format("insert into alert_tag (alert_tag, layer_group, line, task) values ('{0}','{1}','{2}','{3}')", alertTag, group, line, task);
                command.ExecuteNonQuery();
                dbConn.Close();                    
            }                
        }
    }
  1. , вы можете рассмотреть возможность проверки некоторых значений, получаемых изdata.Rows перед сохранением.Вы широко открыты для инъекции SQL прямо сейчас.посмотрите на построение или используя параметры .

  2. я бы исследовал хороший ORM, такой как Dapper или EF, чтобы избежать создания операторов хрупкой вставки

...