.net: не заставить работать базу данных sqlite в памяти

Пытаясь понять использование баз данных SQLite в памяти, я читал об этом в документации по SQLite и (я думаю) почти все, что я мог найти здесь в stackoverflow об этом.

Я хочу скопировать таблицу из локальной базы данных в базу данных в памяти.

Чтобы понять, как работают базы данных SQLite в памяти, я создал этот код:

Private Sub Test()
  Dim intTemp As Integer
  Dim strSQL As String

  Dim conn As New SQLiteConnection("Data Source=':memory:';Version=3;New=True;")
  conn.Open()

  strSQL = "CREATE TABLE Table_1 (Table_1ID [VARCHAR(5)] NOT NULL, Item [VARCHAR(40)]);"
  Dim cmd As SQLiteCommand = New SQLiteCommand(strSQL) With {
      .Connection = conn
    }

  strSQL = "SELECT Count(*) FROM Table_1;"
  ' Test (1): Result: 0
  intTemp = cmd.ExecuteScalar

  strSQL = "INSERT INTO Table_1 (Table_1ID, Item) VALUES ('1000', 'Book');"
  cmd.CommandText = strSQL
  ' Test (2): Result: 1
  intTemp = cmd.ExecuteNonQuery

  strSQL = "SELECT Count(*) FROM Table_1;"
  ' Test (3): Result: 0
  intTemp = cmd.ExecuteScalar
End Sub

Как-то вроде работает: когда я вставляю запись в таблицу, результат равен 1. Но когда я затем считаю записи, результат равен 0.

Есть идеи, что я здесь делаю не так? Есть ли где-нибудь рабочий образец, на C# или в VB.Net? Может быть, даже с решением моей первоначальной проблемы: скопировать таблицу из локальной базы данных в базу данных в памяти? Спасибо!

1
0
668
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В COUNT sql вы забыли изменить CommandText, поэтому вы снова вставили запись.

strSQL = "SELECT Count(*) FROM Table_1;"
cmd.CommandText = strSQL             ' this was missing   '
intTemp = CInt(cmd.ExecuteScalar())  ' Now this returns 1 '

По этой причине рекомендуется использовать несколько команд для разных запросов.

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

Using conn = New SQLiteConnection("Data Source=':memory:';Version=3;New=True;")
    conn.Open()

    Using cmd = New SQLiteCommand("CREATE TABLE Table_1 (Table_1ID [VARCHAR(5)] NOT NULL, Item [VARCHAR(40)]);", conn)
        cmd.ExecuteNonQuery()

        cmd.CommandText = "INSERT INTO Table_1 (Table_1ID, Item) VALUES ('1000', 'Book');"
        Dim inserted as Int32 = cmd.ExecuteNonQuery()

        cmd.CommandText = "SELECT Count(*) FROM Table_1;"
        Dim count = CInt(cmd.ExecuteScalar())
    End Using       
End Using

Спасибо! Не знаю, как часто я проверял свой код, но я его не видел. Спасибо также за подсказку по использованию "Использование"!

Anumi 31.10.2018 14:07

Я играл с этим на C# и получил недопустимое приведение с использованием int. Протестировано с помощью GetType и выяснилось, что он возвращает Int64.

Mary 31.10.2018 21:59

@Mary, вы действительно должны установить Option strict по умолчанию

Tim Schmelter 31.10.2018 22:45

@TimSchmelter У меня всегда включен Option Strict.

Mary 01.11.2018 02:22

@Mary нет, тогда последняя строка im метод не будет компилироваться, потому что ExecuteScalar возвращает Object, но вы назначаете его целочисленной переменной. Сравните с моим кодом. Я использую CInt для его трансляции. редактировать, извините, думал, что вы OP

Tim Schmelter 01.11.2018 02:24

@TimSchmelter int count = (int)cmd.ExecuteScalar(); компилируется нормально, но выдает ошибку времени выполнения - недопустимое приведение. Int64 count = (Int64)cmd.ExecuteScalar(); работает нормально.

Mary 01.11.2018 02:27

Я почти уверен, что вы использовали CType в vb.net, который не совпадает с оператором приведения в C#. Если вам нужно такое же поведение, используйте DirectCast. CType обладает встроенной магией. Convert.ToInt32 будет использоваться, чтобы сделать длинное коротким.

Tim Schmelter 02.11.2018 09:37

Другие вопросы по теме