コード例 #1
0
        /// <summary>
        /// Запаковывает изменения.
        /// Метод можно разбить на несколько кусков, чтобы можно было модифицировать при прикладном использовании.
        /// </summary>
        /// <param name=""></param>
        public void PackChanges(Packaging)
        {
            // Догрузить Packaging.
            DataService.LoadObject(Packaging);

            // Период изменений.
            // Если только dateFrom == null, то брать все изменения до dateTo.
            // Если только dateTo, то брать изменения начиная с dateFrom.
            // Если обе даты == null, то брать все изменения.
            DateTime dateFrom = PackageCollecting.DateFrom;
            DateTime dateTo   = PackageCollecting.DateTo;

            // Читаем факты изменения из БД.
            // Выбираем только факты нужных классов.
            // Сортируем по дате.
            // Порционная вычитка опущена для простоты.
            seClassLimit = In <SyncEntity>(se => se.ClassName, mappingClassNames);
            var syncEntities = DataService.LoadObjects(seClassLimit);

            foreach (var se in syncEntities)
            {
                // Проверим, было ли запаковано изменение в данной синхронизации.
                // Текущая идея - проверять существование такого ObjectChangePackage:
                packagedLimit = And(
                    Equals <ObjectChangePackage>(ocp => ocp.Package.Packaging.Synchronization, SyncID),
                    Equals <ObjectChangePackage>(ocp => ocp.syncEntity, se)
                    );
                var objectChangePackage = DataService.LoadObjects(packagedLimit).FirstOrDefault();

                // Если было, то попробовать взять готовый пакет.
                if (objectChangePackage != null)
                {
                    if (objectChangePackage.data != null)
                    {
                        MessageBuilder.AppendMessage(packaged);
                    }

                    // Если готового пакета нет, то запаковываем.
                }
                else
                {
                    // Выполняем чтение и маппинг.
                    // Если обозреваемый объект превращается в несколько целевых объектов, то маппетов будет несколько.
                    // Базовый механизм маппинга будет таким же, как в прошлом синхронизаторе.
                    var currentMappers = mappers.Where(map => map.GetObservingType() == se.type);
                    foreach (var currentMapper in currentMappers)
                    {
                        // Если еще не запаковывали, то читаем сами изменения из БД приложения.
                        // Тут должно быть по-разному: вариант для старого аудита, и вариант для нового аудита.
                        // Чтение уже реализовано в предыдущих вариантах синхронизаторов.
                        // Например, прочитаем со старым аудитом.
                        // Должны получить сам объект, тип объекта и список измененных атрибутов.
                        var change = PackageHelper.GetChangeFromAppDB(se, tAuditType.Old, map.GetObservingView());

                        // Получаем целевые объекты.
                        var destinationObject = currentMapper.Map(change);

                        // Собираем сообщение.
                        // Скорее всего, messageBuilder будет сам решать, как собирать пакеты, поэтому просто отправлем ему всю информацию об изменениях.
                        messageBuilder.CreateMessage(destinationObject, change, objectChangePackage);
                    }
                }

                // Как только пакет в messageBuilder готов, достаем его и все его сообщения.
                var package = messageBuilder.PopPackage();
                if (package != null)
                {
                    // Пакет сообщения складываем в бд.
                    DataService.UpdateObject(package);
                    package = null;
                }
            }

            // Создать пакет из оставшихся сообщений.
            var forcedPackage = messageBuilder.PopPackageForced();

            DataService.UpdateObject(forcedPackage);

            // Теперь в бд лежат пакеты и составляющие сообщения.
            // Если это будет занимать слишком много памяти,
            // то можно очищать ObjectChangePackage.data (можно и не хранить, но тогда иногда придется упаковывать по нескольку раз)
            // и Package.data (после успешной синхронизации).

            // Как часто поток будет искать в БД объект Package.
            Thread.Sleep(10000);
        }