Choroid Ответов: 2

Vb.net откройте базу данных sqlite в модуле


Я заметил повторяющийся код, когда я хочу предварительно сформировать функцию БД

Я использовал вспомогательную функцию в JavaFX и создал класс openDBUtil, поэтому мне нужно было только вызвать openDBUtil для предварительной обработки функций DB

Я пытаюсь сделать то же самое в VB.Net при использовании модуля из-за взаимозависимости одного оператора от другого это работает не так хорошо

Вопрос в том, возможно ли это вообще?

Если это возможно, как бы я закодировал эту концепцию?
Мой саб который работает так как он сейчас размещен ниже и код в модуле
ДА У МЕНЯ ЕСТЬ ИМПОРТ
Imports System.Data.SqlClient
Imports System.Data.SQLite


Что я уже пробовал:

Private Sub PopulateDGV()

    Dim str2 As String
    Dim s1 As Integer
    Dim dbName As String = "Word.db"
    Dim conn As New SQLiteConnection("Data Source =" & dbName & ";Version=3;")
    Dim valuesList As ArrayList = New ArrayList()
    'openDB() Public Sub in ModuleOne

    'Read from the database
    Dim cmd As SQLiteCommand = New SQLiteCommand("Select * FROM ParentTable", conn)
    conn.Open()
    Dim rdr As SQLite.SQLiteDataReader = cmd.ExecuteReader

    'Set Design of the DataGridView
    dgvOne.DefaultCellStyle.Font = New Font("Tahoma", 10)
    dgvOne.ColumnCount = 2
    dgvOne.Columns(0).Width = 60
    dgvOne.Columns(1).Width = 420
    'To Set Col Header Size Mode = Enabled
    'To Set Col Header Default Cell Styles DO in Properties
    dgvOne.ColumnHeadersHeight = 34

    'DGV Header Names
    dgvOne.Columns(0).Name = "PID"
    dgvOne.Columns(1).Name = "Entry Data"
    dgvOne.Columns(0).SortMode = DataGridViewColumnSortMode.NotSortable
    dgvOne.Columns(1).SortMode = DataGridViewColumnSortMode.NotSortable

    'Read From DB Table add to DGV row
    While rdr.Read()
        valuesList.Add(rdr(1)).ToString()
        lbOne.Items.Add(rdr(1)).ToString()
        s1 = rdr(0).ToString
        str2 = rdr(1)
        dgvOne.Rows.Add(s1, str2)
    End While

    'Add Blank rows to DGV
    For iA = 1 To 4
        dgvOne.Rows.Add(" ")
    Next

    rdr.Close()
    conn.Close()

End Sub


Module ModuleOne

    Public Sub openDB()
        Static dbName As String = "Word.db"
        Static conn As New SQLiteConnection("Data Source =" & dbName & ";Version=3;")
        Static cmd As SQLiteCommand = New SQLiteCommand("Select * FROM ParentTable", conn)
        conn.Open()
        Static rdr As SQLite.SQLiteDataReader = cmd.ExecuteReader
        'conn.Close()
    End Sub

End Module


Улучшенный код от OriginialGiff
Private Sub GetDB()
    Dim str2 As String
    Dim s1 As Integer
    'Dim strConnect As String
    'strConnect = "Data Source={0};Version=3;"
    Dim dbName As String = "Word.db"
    Using con As New SQLiteConnection("Data Source =" & dbName & ";Version=3;")
        'Using con As New SqlConnection(strConnect)
        con.Open()
        'Using cmd As New SqlCommand("SELECT * FROM ParentTable", con)
        Using cmd As SQLiteCommand = New SQLiteCommand("Select * FROM ParentTable", con)
            'Using reader As SqlDataReader = cmd.ExecuteReader
            Using reader As SQLite.SQLiteDataReader = cmd.ExecuteReader
                While reader.Read()
                    s1 = reader(0).ToString
                    str2 = reader(1)
                    lbOne.Items.Add(s1 & " " & str2)

                    'Dim id__1 As Integer = CInt(reader("iD"))
                    'Dim desc As String = DirectCast(reader("description"), String)
                    'lbOne.Items.Add(desc.ToString())
                    'Console.WriteLine("ID: {0}" & vbLf & "    {1}", desc)
                End While
            End Using
        End Using
    End Using
End Sub

Garth J Lancaster

Вы сказали: "это не так хорошо работает" - не могли бы вы использовать Улучшить вопрос чтобы указать "почему бы и нет" - это может помочь людям узнать, что вам нужно, мне не совсем ясно, о чем именно вы просите

В общем, да, это должно быть возможно - посмотрите вот, например https://www.codeproject.com/Articles/1210189/Using-SQLite-in-Csharp-VB-Net -да ... если вы хотите быстро критиковать "ModuleOne", хорошо ..
1) ModuleOne - это плохое имя и не указывает на его назначение-например, vs 'sqliteDBModule' (я забываю соглашения VB 'case' )
2) openDB делает слишком много - он должен взять, может быть, Имя/Путь к БД и вернуть соединение с БД или ошибку (или даже выбросить исключение), вот и все - одна цель
3) Вы можете расширить свой "модуль" Sqlite для реализации openDB, closeDB, executeSQL и т. д. и т. д., Но, конечно, я бы сказал, что рассмотрите то, что уже есть, и повторно используйте/расширьте его
4) в дополнение к (3), я бы сказал, Подумайте о "слоях" / "абстракциях" .. на самом нижнем уровне у вас есть модуль базы данных sqlite, который делает только низкоуровневые вещи с любой базой данных. "Поверх" этого слоя вы затем создаете модули, специфичные для данных, которые вы хотите обработать - возможно, по одному модулю на базу данных или таблицу

Помогает ли это вам или приближает вас к тому, что вам нужно ?

Редактировать - тоже полезно, https://github.com/praeclarum/sqlite-net, https://blog.maskalik.com/asp-net/sqlite-simple-database-with-dapper/

2 Ответов

Рейтинг:
20

OriginalGriff

В этом подходе есть так много неправильных вещей: метод "open" делает select, который создает DataReader на соединении, делая соединение непригодным для использования до тех пор, пока считыватель не будет закрыт, а поскольку "внешний мир" вообще не может получить доступ к считывателю, соединение все равно не может быть использовано.
Нет никакого способа принудительно закрыть и утилизировать используемые скудные ресурсы: соединение, команда и считыватель-все это объекты, которые необходимо утилизировать должным образом, иначе ваше приложение довольно быстро закончится.
Имя БД и имя таблицы жестко закодированы в модуле, что означает, что он не может быть использован повторно.
Заполнение DGV будет лучше выполняться из DataAdapter, чем из DataReader, а DataTable будет использоваться в качестве источника данных.
Выбор предполагает порядок столбцов, как и код заполнения DGV. Не используйте SELECT * - перечислите нужные вам столбцы.
SELECT собирает все столбцы, и это расточительно, если есть какие-то столбцы, которые вам не нужны на этот раз. Опять же, перечислите нужные столбцы, а не используйте SELECT *
Как только ваши запросы становятся более сложными, вам приходится либо писать невероятно гибкие методы модулей, либо оставлять себя широко открытыми для SQL-инъекций, которые могут повредить или уничтожить вашу БД.
Как правило, вы не можете "модульизировать" доступ к БД до нужного уровня, так как вам понадобятся новые идентичные методы модулей для каждой таблицы и запроса, а большинство БД имеют много таблиц!

Делайте это в своем методе, когда вам это нужно, и используйте Using заявления для контроля выбытия, когда товары выходят за рамки области применения:

Using con As New SqlConnection(strConnect)
	con.Open()
	Using cmd As New SqlCommand("SELECT iD, description FROM myTable", con)
		Using reader As SqlDataReader = cmd.ExecuteReader()
			While reader.Read()
				Dim id__1 As Integer = CInt(reader("iD"))
				Dim desc As String = DirectCast(reader("description"), String)
				Console.WriteLine("ID: {0}" & vbLf & "    {1}", iD, desc)
			End While
		End Using
	End Using
End Using


Choroid

Включив "использование" ресурсов, утилизированных да лучше идея, которую я знал, что просто было уместно реализовать
DGV fill я хотел вручную управлять добавлением к DGV я написал код который использовал считыватель и datatable
ParentTable имеет только два значения PID и Name
В то время как этот проект будет только вставлять и создавать две таблицы, я понимаю, что вы говорите не очень хорошая идея "modularize"
Я буду публиковать улучшенный код закомментированный код думаю не очень хорошая идея вставлять код ? Я не знаю, как обойти БД с жестко закодированным именем и таблицей?
После того, как я подумал, реализуя "использование" , мне все еще нужно мошенничать.Закрыть & читатель.Близко?
Спасибо Вам за ответ, который дал много знаний и ценных советов

Рейтинг:
1

Maciej Los

Если вы хотите переместить/экспортировать часть вашего кода, ответственную за обмен данными с базой данных, вы должны создать набор процедур/функций в этом модуле. По крайней мере:
1. Function GetDataTable(qry, qry_parameters) As DataTable - захватывает данные из базы данных на основе переданного запроса и возвращает объект DataTable
2. Function InsertData(qry, qry_parameters) As Integer - вставляет данные и возвращает количество затронутых строк
3. Function UpdateData(qry, qry_parameters) As Integer - обновляет данные и возвращает количество обновленных строк
4. Function DeleteData(qry, qry_parameters) As Integer - удаляет данные и возвращает количество удаленных строк

Вы также можете создать отдельные функции для открытия и закрытия соединения.

Я бы настоятельно рекомендовал прочитать это:
Создание уровня доступа к данным (VB) | Microsoft Docs[^]
Создание уровня бизнес-логики (VB) | Microsoft Docs[^]


Choroid

Спасибо за советы и ссылки похоже я могу использовать модуль не уверен что мне будет просто лень писать один и тот же код на разных формах