2013-06-06 2 views
1

У меня есть быстрый вопрос о VBNET, в настоящее время я использую VS 2012 Express и Microsoft Access в качестве моей базы данных.Хранить все запросы внутри модуля?

Вопрос в том, как разместить свои запросы в модуле вместо того, чтобы поместить запросы в форму? Скажем, у меня есть эта функция в frmStock:

frmStock:

Public Sub FillCategory(ByVal Key As String, ByVal Txt As String, ByVal N As TreeNode) 
    Dim TD As TreeNode 

    If N Is Nothing Then 
     TD = tvCategory.Nodes.Add(Key, Txt) 
    Else 
     TD = N.Nodes.Add(Key, Txt) 
    End If 

    Dim cmd As New OleDbCommand("SELECT * FROM Category WHERE Category_Parent = ?", conn) 
    cmd.Parameters.AddWithValue("Category_Parent", Key) 

    Dim dr = cmd.ExecuteReader 
    Do While dr.Read() 
     FillCategory(dr("Category_ID"), dr("Category_Name"), TD) 
    Loop 
    dr.Close() 
    cmd.Dispose() 
End Sub 

Я хочу, чтобы переместить

Dim cmd As New OleDbCommand("SELECT * FROM Category WHERE Category_Parent = ?", conn) 

в модуль вместо этого.

Я попытался сделать:

Module queryCollection 

    Public getCategoryParent As New OleDbCommand(_ 
      "SELECT * FROM Category WHERE Category_Parent = ?", conn) 

End Module 

И доработанную мою функцию FillCategory к:

Public Sub FillCategory(ByVal Key As String, ByVal Txt As String, ByVal N As TreeNode) 
    Dim TD As TreeNode 

    If N Is Nothing Then 
     TD = tvCategory.Nodes.Add(Key, Txt) 
    Else 
     TD = N.Nodes.Add(Key, Txt) 
    End If 

    getCategoryParent.Parameters.AddWithValue("Category_Parent", Key) 

    Dim dr = getCategoryParent.ExecuteReader 

    Do While dr.Read() 
     FillCategory(dr("Category_ID"), dr("Category_Name"), TD) 
    Loop 
    dr.Close() 
    getCategoryParent.Dispose() 
End Sub 

UPDATE:
Некоторые Снимок экрана для моей проблемы:

Моя база данных: http://puu.sh/39CMV.PNG

, прежде чем перейти мой запрос в модуль: http://puu.sh/39D0M.PNG

Перебравшись мой запрос в модуль: puu.sh/39CVV.PNG

Казалось, как выполнить только один раз Почему это и что (?) является правильным способом объявления моих запросов в модуле?

У меня на самом деле есть тонны запросов, я хочу хранить их в одном месте для более упорядоченного кодирования.

+1

вам действительно нужно хранить запросы делать? Не можете ли вы использовать что-то вроде LINQ to SQL или LINQ to EF? Было бы намного лучше, чем иметь строковые литералы в вашем коде. –

+0

@DoctorJones, привет спасибо за ваш ответ, я еще не встречал LINQ, и я использую Microsoft Access в качестве моей базы данных. Я хочу хранить все свои запросы в модуле, в основном потому, что в моем кодировании слишком много запросов, оно выглядит таким грязным, мне нужно его организовать. –

+1

Я бы очень хотел посмотреть LINQ to SQL. Он исключает все строковые литералы в вашем коде и вместо этого заменяет их строго типизированными запросами. Это означает, что вы будете ловить орфографические ошибки и т. Д. Во время компиляции, а не во время выполнения, и упростит ваш код. –

ответ

0

В коде изменен FillCategory вы назвали следующие, но не сохранили результат:

getCategoryParent.Parameters.AddWithValue("Category_Parent", Key) 

, который создал OleDbCommand объект, но затем он сразу же отбрасывается. Затем вы звоните:

Dim dr = getCategoryParent.ExecuteReader 

который создает второй OleDbCommand объект, но без значения параметра.

Измените код, как:

Dim cmd = getCategoryParent.Parameters.AddWithValue("Category_Parent", Key) 
Dim dr = cmd.ExecuteReader 

EDIT: Ниже будут рассмотрены обе проблемы.

Dim cmd = getCategoryParent 
cmd.Parameters.AddWithValue("Category_Parent", Key) 
Dim dr = cmd.ExecuteReader 

Ранее переменная cmd была быть Infer ред от VB быть OleDbParameter объект, который не имеет метод ExecuteReader. Это было выведено таким образом из-за того, как он был вызван с кодом .Parameters.AddWithValue("Category_Parent", Key), сделанным встроенным.

С этим изменением cmd правильно установлен в переменную OleDbCommand, и теперь вы можете использовать метод AddParameter столько раз, сколько необходимо.

EDIT 2: getCategoryParent в настоящее время определяется как свойство модуля. Это означает, что метод getCategoryParent выполняется один раз, когда модуль сначала создается, а не один раз в цикл. Измените этот метод как функцию, и теперь код будет выполняться один раз за цикл, и ваш TreeView будет загружен, как вы ожидаете.

Public Function getCategoryParent() As OleDbCommand 
    Return New OleDbCommand("SELECT * FROM Category WHERE Category_Parent = ?", conn) 
End Function 
+0

Здравствуйте, спасибо за указание моей ошибки. Однако я только что попробовал изменить свой код, и он дал мне ошибку в строке: Dim dr = cmd.ExecuteRead // 'ExecuteReader' не является членом 'System.Data.Oledb.OleDbParameter' Также еще один быстрый вопрос, если у меня есть более одного параметра для прохождения, как его передать? Спасибо. –

+0

@MiloJuakMuTou - Смотрите мои правки для обеих точек. –

+0

Здравствуйте, я попробовал ваш код, и теперь он работает :) Но когда я запускаю код, он выглядит как только один раз, я предоставил SS для получения дополнительной информации: Моя база данных: [База данных] (http://puu.sh /39CMV.PNG) Как мой код работает без моего запроса: [Нет ошибки] (http://puu.sh/39D0M.PNG) Как мой код работает после перемещения моего запроса: [Ошибка] (http://puu.sh/39CVV.PNG) Как я называю свою функцию FillCategory(): FillCategory ("1", "Все категории", ничего) Спасибо. –

0

Один подход, который я взял с ASP.NET и доступ был, чтобы сохранить мой SQL как файлы в папку и загрузить его с помощью может быть одноэлементно так:

Public Class FileHandler 

    Public Shared Function LoadToString(ByVal pName As String) As String 
     Dim rV As String 
     Dim fio As StreamReader = File.OpenText(pName) 
     rV = fio.ReadToEnd() 
     fio.Close() 
     Return rV 
    End Function 

End Class 

Затем вызовите его из кода ...

... 
dim sqlStr As String = FileHandler.LoadToString("sql/mySqlStatement.sql") 
... 

Это, скорее всего, не лучшее решение. Главное преимущество этого заключается в том, что вы можете модифицировать SQL на лету, не перекомпилируя приложение.

Альтернативой является сохранение ваших операторов SQL в качестве пар значений имени в вашем web.config, но опять же это не очень хорошее решение.

Если у кого-то нет лучшего предложения с этим, я думаю, что это будет лучший из худшего выбора!

+0

Привет, спасибо за ответ, я не думаю, что хранить запросы в текстовом файле - это хорошая идея, возможно, это приведет к созданию большого количества файлов, если у меня есть, 20 запросов? –

+0

Только 20? Вы можете загрузить те, которые вам нужны в начале приложения. – Paul

0

Как насчет поставить SQL строку на вашем модуле ..

Module queryCollection 

    Public sCatParent As String = "SELECT * FROM Category WHERE Category_Parent = ?" 

End Module 

И вы называете это как ..

getCategoryParent As New OleDbCommand(sCatParent,conn) 

getCategoryParent.Parameters.AddWithValue("Category_Parent", Key) 

Dim dr = getCategoryParent.ExecuteReader 
+0

Привет, эта работа отлично! Однако я все еще жду более эффективный код, также я хотел знать, почему мой код выполняется только один раз. Во всяком случае, спасибо много: D Я буду использовать это, если нет лучшего ответа <3 –

Смежные вопросы