У меня есть приложения winforms с серверной частью сервера ms sql. В моей базе данных у меня есть таблицы поиска для подобного статуса и другие таблицы, где данные редко меняются. В моем приложении несколько форм могут использовать одни и те же таблицы поиска (некоторые из них содержат много данных). Вместо того, чтобы загружать/заполнять данные каждый раз, когда форма открыта, есть ли способ кэшировать данные из базы данных, к которым можно получить доступ из нескольких форм. Я немного поискал, но не нашел лучшего решения. Есть кеширование, словари и т.д. Какое лучшее решение и можете ли вы указать мне на документацию, в которой это обсуждается и, возможно, даже есть пример.
Редактировать: В своем исходном посте я не упомянул, что у меня строго типизированный набор данных и я использую адаптеры таблиц. Я хочу предварительно загрузить свои таблицы поиска при запуске моего приложения, а затем использовать эти таблицы наборов данных во всем приложении в нескольких формах без необходимости заполнять их в каждой форме.
Я попытался создать класс:
Public Class dsglobal
Public Shared EML_StaffingDataSet As EML_StaffingDataSet
Public Shared Sub populateDS()
EML_StaffingDataSet = New EML_StaffingDataSet
End Sub
Public Shared Sub loadskills()
Dim ta As New EML_StaffingDataSetTableAdapters.TSTAFFSKILLTableAdapter
ta.Fill(EML_StaffingDataSet.TSTAFFSKILL)
End Sub
End Class
Я запускаю это в фоновом режиме, когда мое приложение запускается. Таким образом, он загружает таблицу набора данных. При заполнении я вижу, что в таблице данных есть данные. Когда я открываю форму, я хочу использовать таблицу набора данных, но, похоже, данные удаляются. Не уверен, что мой подход правильный или где моя ошибка.
Редактировать2: Я также пробовал это в комментариях, но не уверен, что делаю это правильно. Если я делаю это правильно, то как мне использовать это в качестве источника данных во время разработки, могу ли я сделать это только программно?
Public Module lookupdata
Private EML_StaffingDataSet As EML_StaffingDataSet
Private skillvalues As List(Of skill)
Public ReadOnly Property skill As List(Of skill)
Get
If skillvalues Is Nothing Then
getskillvalues()
End If
Return skillvalues
End Get
End Property
Private Sub getskillvalues()
skillvalues = New List(Of skill)
EML_StaffingDataSet = New EML_StaffingDataSet
Dim ta As New EML_StaffingDataSetTableAdapters.TSTAFFSKILLTableAdapter
ta.Fill(EML_StaffingDataSet.TSTAFFSKILL)
For Each row As DataRow In EML_StaffingDataSet.TSTAFFSKILL
Dim skill As New skill
skill.skill_id = row("skill_id")
skill.skill_desc = row("skill_desc")
skill.skill_open_ind = row("skill_open_ind")
skillvalues.Add(skill)
Next
End Sub
End Module
Public Class skill
Public Property skill_id As Integer
Public Property skill_desc As String
Public Property skill_open_ind As Boolean
End Class
Я думаю, что я ищу, как сделать глобальный набор данных.
how do I use that as a datasource at design time вы имеете в виду именно источник данных управления winforms?
Я так думаю. Как мне создать глобальный набор данных из моего уже созданного строго типизированного набора данных, который можно использовать во всем моем приложении в качестве источника данных управления winforms.
В сочетании с ответом ниже, я думаю, он у вас есть. Добавьте свой элемент управления, щелкните стрелку свойств, выберите источник данных, добавьте источник данных проекта, объект, далее, разверните свой проект, содержащий модуль, до свойства «навык», проверьте «навык», Готово. Вы увидите, что дизайнер сгенерировал SkillBindingSource внизу. И ваш элемент управления должен быть заполнен свойствами класса skill.
Я бы добавил, что общедоступное свойство вашего модуля, в котором есть ваши данные, вероятно, должно иметь тип IEnumerable(Of Skill), а не Список (навыков). Разница в том, что список предоставляет такие методы, как Add, Clear, Remove и т. д., которые вы, вероятно, не хотите предоставлять потребителю, который IEnumerable предназначен для потребителя только для перечисления/чтения результатов.
@djv, так что мое редактирование номер два выглядит правильно, за исключением того, что вместо этого я должен использовать ienumerable? Мне придется посмотреть еще раз, потому что я пробовал добавить источник данных, как вы сказали, и я его не видел. Позвольте мне попробовать еще раз, посмотреть, что я упускаю. Спасибо за помощь, я очень ценю это.
@djv Хорошо, я нашел это, когда добавлял источник данных проекта. Я добавил его в управление, но когда я запускаю приложение, данных нет. Это похоже на то, что свойство никогда не заполняется. Как срабатывает getvalues, чтобы он заполнил свойство значениями из базы данных? Кроме того, когда я смотрю на skillbindingsource, я вижу, что источником данных является навык, должен ли быть член данных?
Это может вам помочь: stackoverflow.com/a/5147579/832052
Я близок, в свойстве навыка есть данные, но когда я выбираю его в качестве источника данных и он добавляет источник привязки, данных нет.
он видел мой класс навыков, а не собственность. Он не видит свойство, потому что оно находится в модуле, а не в классе?
Я так думаю. Вы можете поместить его в класс и сделать класс синглтоном по моей ссылке. Моя ссылка почти такая же, как и ваш вопрос, за исключением того, что она написана на С#.
@djr. Итак, я вроде как заработал, но в своей форме я должен указать Dim lu As New lookupdata; SkilllistBindingSource.DataSource = lu.skilllist; skillsCLBC.DataSource = SkilllistBindingSource.DataSource; пытаясь выяснить, как обойти это программно.

Возможно, вы захотите рассмотреть шаблон ленивой загрузки, например:
Public Module LookupData
Private statusValues As List(Of LookupValue)
Public Readonly Property Statuses As List(Of LookupValue)
Get
If statusValues Is Nothing Then
GetStatusValues()
End If
Return statusValues
End Get
End Property
Private Sub GetStatusValues()
statusValues = New List(Of LookupValue)
Dim sql = "select key, value from StatusTable"
'TODO: Read the items from the database here, adding them to the list.
End Sub
End Module
Public Class LookupValue
Public Property Key As String
Public Property Value As String
End Class
Идея состоит в том, что у вас есть один экземпляр LookupData (модуль в VB, может быть только один). Данные поиска имеют ряд свойств, каждое из которых возвращает список значений из базы данных. Если данные уже были загружены, он просто возвращает то, что было закешировано. Если данные не были загружены, то при первом обращении к ним они извлекаются из базы данных.
Вы можете использовать его в другом месте вашего кода следующим образом:
Dim myStatuses = LookupData.Statuses
но что, если таблица базы данных имеет больше, чем поле ключа и поле значения. Он может состоять из 2+ столбцов
Вы можете добавить любое количество свойств в класс LookupValue, а также можете иметь несколько классов для разных структур записей.
Вместо того, чтобы возвращать List(Of LookupValue), создайте класс, который инкапсулирует все состояние вашей базы данных, и верните его. Это похоже на метод статической фабрики.
скажем, я использую наборы данных и адаптеры таблиц во всем своем приложении. прямо сейчас я заполняю каждый, как «Me.TSTAFFSKILLTableAdapter.Fill(Me.EML_StaffingDataSet.TSTAFFSKILL)». Какой лучший вариант, когда я загружаю данные таким образом?
@djv, я обновил свой вопрос некоторыми обновлениями. Должно было быть яснее в моем исходном посте.
Как бы просто это ни было, вы можете создать отдельный проект, в котором у вас есть статический класс с некоторым свойством, представляющим кэшированные данные. Когда вы используете свойство, вы проверяете, было ли инициализировано статическое поле базового свойства. Если не инициализировать его (загрузка данных из базы данных), если да, просто верните статическое поле.