Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB .NET > Помогите с перебором данных мастер-деталь


Автор: barulya 13.11.2009, 18:48
Доброго времени суток!
У меня имеется три набора данных связанных по связи мастер-деталь последовательно: организации-объекты-здания, соответствующие таблицы данных связаны по определенным ключевым полям.
Данные из этих таблиц размещены в контроле, унаследованном от TreeView согласно их уровню в иерархической структуре. Для связи контролов и данных созданы три bindingsource (назовем их условно А, Б и В) для каждой таблицы данных. Так вот при построении дерева курсор в А установлен на первой записи, в Б и В данные отфильтрованы в соответствии с таблицей А. Если начать перебирать все записи в табл. А и во вложенных циклах данные табл Б и В то, в связи с тем, что А, Б и В связаны с другими контролами, заметно увеличиватся время добавления ветвей дерева.
Подскажите пожалуйста, как отключить контролы от bindingsource для ускорения заполнения дерева? Или может быть можно перебрать строки подчиненных таблиц не меняя позиции соответствующих мастер таблиц.
Вот код, при помощи которого я строю дерево:
Код

    Public Sub BuildStructure()
        Dim intOrgID, intObjID, intBrID As Integer
        Dim rwOrg, rwObj, rwBR As Object
        Dim i, j, k As Integer
        Dim strOrgName, strObjName, strBRName As String
        Dim pdOrgPDColl, pdObjPDColl, pdBRPDColl As System.ComponentModel.PropertyDescriptorCollection
        Dim newORG, newOBJ, newBR As TreeNode
        Me.BeginUpdate()
        Me.Nodes.Clear()
         pdOrgPDColl = _bsorgcm.GetItemProperties()
        pdObjPDColl = _bsobjcm.GetItemProperties()
        pdBRPDColl = _bsbrcm.GetItemProperties()

        For i = 0 To _bsorgcm.Count - 1
            _bsorgcm.Position = i
            rwOrg = _bsorgcm.Current
            intOrgID = CType(pdOrgPDColl(_strorgvm).GetValue(rwOrg), Integer)
            strOrgName = CType(pdOrgPDColl(_strorgdm).GetValue(rwOrg), String)
            newORG = New Organization(intOrgID, strOrgName)
            If Not _orgs.ContainsKey("org" & intOrgID) Then _orgs.Add("org" & intOrgID, newORG)
            Me.Nodes.Add(newORG)
            For j = 0 To _bsobjcm.Count - 1
                _bsobjcm.Position = j
                rwObj = _bsobjcm.Current
                intOrgID = CType(pdObjPDColl(_strobjpm).GetValue(rwObj), Integer)
                intObjID = CType(pdObjPDColl(_strobjvm).GetValue(rwObj), Integer)
                strObjName = CType(pdObjPDColl(_strobjdm).GetValue(rwObj), String)
                newOBJ = New OrgObj(newORG, intObjID, strObjName)
                If Not _orgs.ContainsKey("obj" & intObjID) Then _orgs.Add("obj" & intObjID, newOBJ)
                newORG.Nodes.Add(newOBJ)
                For k = 0 To _bsbrcm.Count - 1
                    _bsbrcm.Position = k
                    rwBR = _bsbrcm.Current
                    intObjID = CType(pdBRPDColl(_strbrpm).GetValue(rwBR), Integer)
                    intBrID = CType(pdBRPDColl(_strbrvm).GetValue(rwBR), Integer)
                    strBRName = CType(pdBRPDColl(_strbrdm).GetValue(rwBR), String)
                    newBR = New Building(newOBJ, intBrID, strBRName)
                    If Not _orgs.ContainsKey("bld" & intObjID) Then _orgs.Add("bld" & intObjID, newBR)
                    newOBJ.Nodes.Add(newBR)
                Next
            Next
        Next
        Me.EndUpdate()
    End Sub

Автор: diadiavova 13.11.2009, 19:11
Цитата(barulya @  13.11.2009,  18:48 Найти цитируемый пост)
Подскажите пожалуйста, как отключить контролы от bindingsource для ускорения заполнения дерева? 

Видимо так же как и подключил - при помощи свойства DataSource.

Автор: barulya 13.11.2009, 20:08
Насколько я понял, то нужно перебирать все контролы и указывать для каждого BindingSource=Nothing.
Если так, то уменя получается это около 60-ти контролов... Как быть перебирать их вручную? И второй вопрос из конструктора дерева не видно какие это контролы.

Автор: diadiavova 13.11.2009, 20:22
barulya, я из кода ничего не понял, да это и не мудрено, это всё-таки фрагмент. К тому же фрагмент ссылающийся на множество объектов, объявленных за пределами приведённого фрагмента. Если неясно какие именно контролы надо отвязывать от источника данных, тогда не знаю что тут можно сделать, но если всё-таки есть способ их определить, то можно загнать их в коллекцию и в отдельном методе перебирать эту коллекцию и выполнять над ними нужные действия.

Но тут есть другой вопрос, а почему на время построения дерева не отключить сами байндингсорсы от таблиц? В конце концов отбор данных и вручную выполнить несложно. При помощи тех же линк-запросов например.

Автор: barulya 13.11.2009, 20:32
Так, если отключить байдингсорсы от таблиц, данные также будут доступны?

Автор: diadiavova 13.11.2009, 20:37
Цитата(barulya @  13.11.2009,  20:32 Найти цитируемый пост)
Так, если отключить байдингсорсы от таблиц, данные также будут доступны?

Дык смотря где. К таблицам ты имеешь и прямой доступ, а в чём проблема то? Байндингсорсы нужны для управления привязкой данных к контролам, а сами данные доступны и безо всяких байндингсорсов. Мало того, при необходимости можно и к контролам подключить таблицу непосредственно, просто тогда нельзя будет некоторые действия выполнять, типа фильтрации данных, синхронизации перемещения указателя и прочего. Если данные просто надо использовать для построения дерева, то байндингсорсы тут вообще не при чём.

Автор: barulya 13.11.2009, 20:39
А с линк-запросами не работал, попробую в этом направлении, спасибо. Я пытался SuspendBinding и ResumeBinding использовать перед перебором и после него соответственно. Но при этом обратиться к текущей записи было не возможно, и не изменялся Position.

Автор: diadiavova 13.11.2009, 20:46
barulya, не видя задачи целиком сложно что-либо советовать. Построение дерева по данным представленным в виде линейных списков - задача не такая уж и сложная, но при чём тут связывание с данными я честно говоря не вполне врубился, так что не знаю, может я тебя и не туда направил smile 

Автор: barulya 13.11.2009, 22:24
Собственно цель, которю я преследовал, ускорение создания дерева, в списке около 3 тыс. орг-ций, чуть больше объектов и раза в полтора больше зданий.  Я делал прямым обращением к дататейбл, но после перехода к байндингсорс заметил, что процесс намного быстрее происходит. Но проблема состояла в том, что я мог загрузить только организации, и только в первую организацию добавлялись объекты, и в свою очередь в первый объект добавлялись здания. Т.е. в байдингсорсах объектов и зданий курсор записи фильтровались по курсору байдингсорса организаций. И еще работать с данными придется и другим частям приложения и отследить в каком из процессов были изменены, добавлены или удалены данные (синхронизировать) будет сложнее. По событиям байдингсорсов это на мой взгляд будет проще. или иначе каждый раз перезагружать всю структуру из базы данных.

Автор: diadiavova 14.11.2009, 00:42
А как вся система связана с контролами, подключенными к байдингсорсам и которые тормозят загрузку?

Автор: barulya 14.11.2009, 10:27
Не понял вопроса?

Автор: diadiavova 14.11.2009, 11:22
Цитата(barulya @  14.11.2009,  10:27 Найти цитируемый пост)
Не понял вопроса?

Ну ты пишешь
Цитата(barulya @  13.11.2009,  18:48 Найти цитируемый пост)
Подскажите пожалуйста, как отключить контролы от bindingsource для ускорения заполнения дерева?

Вот я и спрашиваю: "Какие контролы и каким образом они влияют на заполнение дерева?".

Автор: barulya 14.11.2009, 12:01
Среди забинденных контролов есть текстбоксы, комбобоксы, чекбоксы, а также таблица "объекты" связана с 4-мя таблицами по приципу мастер-деталь, а таблица "здания" имеет 8 связанных таблиц по томуже принципу, которые в свою очередь забиндены с DataGridView. И как следствие тормозит команда bindingsource.position при его смене.
Чтобы иметь общее представление о количестве данных прикрепляю картинку:

Автор: diadiavova 14.11.2009, 12:22
barulya, я понимаю, что у тебя какая-то сложная структура данных и всё такое, но я уже сколько бьюсь никак не могу добиться ответа на вопрос, как байндингсорсы связаны с сабжем. В заголовке темы и первом посте речь шла о проблемах с формированием дерева, теперь ты говоришь о тормозах при перемещении указателя. Из этого я делаю вывод, что данные для формирования дерева ты вытаскиваешь то ли из грида, то ли из ещё какого-то контрола, список элементов в котором фильтруется при помощи байндингсорса. Если проблема именно в этом, то я уже ответил - строй дерево по данным из таблиц, а не из контролов. Если я опять тебя не понял, значит видно не судьба.

Автор: barulya 14.11.2009, 23:58
diadiavova, 
Я вытягивал данные напрямую из таблиц используя байдингсорсы, но при этом в байдингсорсах объектов и зданий в свойствах датасорс указывал соответствующую родительскую таблицу, а в датамембер указывал связи с дочерними таблицами. Заполнял дерево при возникновении событий ListChanged со значение Reset каждого байдингсорса внутры конструктора дерева. т.е. я его заполнял не из внешнего кода, а так сказать изнутри перебирая последовательно по иерархии строки в каждом списке. И перебирая соответственно каждые строки у меня происходили множественные фильтрования списков и привязки к контролам. Я делал это для того, чтобы быстрее и удобнее синхронизировать изменение положения курсора в дереве и байдингсорсах (используя значения индексов элементов). Но к сожалению я пошел по неверному пути.  После того как в байдингсорсах в значении свойств датасорс я указал свой датасет, а в значениях датамембер я указал соответствующие таблицы. Теперь мне стали доступны все элементы списков подчиненных таблиц без фильтрования, что дает мне возможность заполнения дерева. Просто при выборе элемента возвращается его ИД и по нему используя поиск устанавливается курсор на нужную запись в байдингсорсах. Так что проблема я думаю решена. Спасибо за внимание и уделенное время.

Автор: diadiavova 15.11.2009, 05:40
Цитата(barulya @  14.11.2009,  23:58 Найти цитируемый пост)
Я вытягивал данные напрямую из таблиц используя байдингсорсы
Когда я писал "напрямую", я имел в виду НЕ используя байдингсорсы. То что ты описал - ужас, летящий на крыльях ночи в общем то и должно было тормозить. Тебе просто надо было заполнить дерево без всякой привязки и отлавливать перемещение фокуса по узлам дерева. А в обработчике этого события уже менять указатели байндингсорсов, фильтры и всё, что надо было менять.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)