MoveToBottom возвращает eInvalidInput после DeepClone.

Автор Тема: MoveToBottom возвращает eInvalidInput после DeepClone.  (Прочитано 4485 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн LisАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 1
Здравствуйте.
Столкнулся со следующей ситуацией: мне нужно получать клоны полигонов (MPolygon) и далее проводить с ними некоторые манипуляции (задавать штриховку и тд). Столкнулся изначально с тем, что Clone() мне возвращал клона без базы данных (null в поле Database), из-за чего в дальнейшем сбоил AddNewlyCreatedDBObject(). Отыскал на этом форуме много информации о том, что использовать Clone из всех вариантов клонирования наиболее небезопасный. Стал использовать DeepClone(), база данных у клона появилась, всё вроде бы замечательно, да только новая беда -- в MoveToBottom() передаются Id клонов, однако вылетает исключение eInvalidInput.
Всё проходит в рамках одной транзакции. В чём может быть проблема?
Прикрепляю небольшой кусочек кода, в котором происходит описанное выше (ключевые моменты: создание клона -- 12 строчка, AddNewlyCreatedDBObject -- 17 строчка, MoveToBottom -- 29 строчка, транзакция оборачивает эту логику в using'е).
Код - C# [Выбрать]
  1. foreach (var objectId in objectIds)
  2. {
  3.         using (var polygon = SelectionHelper.GetCadPolygon(objectId, transaction, OpenMode.ForWrite))
  4.         {
  5.                 if (polygon == null)
  6.                         continue;
  7.  
  8.                 if (style == null)
  9.                         continue;
  10.  
  11.                 var idMap = new IdMapping();
  12.                 using (var clonePolygon =  (Entity)polygon.DeepClone(blockTableRecord, idMap, false))
  13.                 {
  14.                         clonePolygon.SetDatabaseDefaults();
  15.                         clonePolygon.Layer = layerNamePlan;
  16.  
  17.                         transaction.AddNewlyCreatedDBObject(clonePolygon, true);
  18.                         objectIdCollection.Add(clonePolygon.ObjectId);
  19.  
  20.                         GeometryClassSetter.SetStyle(clonePolygon, classItem, Common.CadDatabase, transaction, Condition.ADDED_TO_PLAN);
  21.                         GeometryClassSetter.SetLandType(clonePolygon, classItemPlan.ClassID, transaction);
  22.                 }
  23.         }
  24. }
  25.  
  26. if (objectIdCollection.Count > 0)
  27. {
  28.         var drawOrderTable = (DrawOrderTable)transaction.GetObject(blockTableRecord.DrawOrderTableId, OpenMode.ForWrite);
  29.         drawOrderTable.MoveToBottom(objectIdCollection);
  30. }

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Я бы посоветовал клонировать объекты вот так

Оффлайн LisАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 1
клонировать объекты вот так
Благодарю.
На самом деле, пытался (аналогичный вариант находил где-то здесь, но и как в статье только что попробовал) и возникает ошибка при AddNewlyCreatedDBObject: eNotNewlyCreated (хотя тут уже база данных, если верить отладке, у клонов вполне себе имеется).

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Как-то плохо вы почитали и попробовали. При использовании DeepCloneObjects никаких манипуляций с AddNewlyCreatedDBObject не требуется. После вызова DeepCloneObjects вы получаете заполненный IdMapping из которого получаете ObjectId дубликата. По ObjectId открываете уже (на запись) дубликат и делаете с ним все ваши грязные делишки

Оффлайн LisАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 1
Как-то плохо вы почитали и попробовали. При использовании DeepCloneObjects никаких манипуляций с AddNewlyCreatedDBObject не требуется. После вызова DeepCloneObjects вы получаете заполненный IdMapping из которого получаете ObjectId дубликата. По ObjectId открываете уже (на запись) дубликат и делаете с ним все ваши грязные делишки
Тут Ваша правда, я немного не так понял для себя смысл DeepCloneObjects(). :)

Однако хотелось бы в итоге не уходить от DeepClone() далеко и попытаться как-то от него раскрутиться. В конце концов, возможно, можно обойтись малой кровью и спрятать MoveToBottom()...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Lis,
Ты не добавил в базу клон. Соответственно у него нет ObjectId и для него нельзя использовать MoveToButton. Где-то в коде не хватет вызова AppendEntity.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LisАвтор темы

  • ADN OPEN
  • Сообщений: 27
  • Карма: 1
Где-то в коде не хватет вызова AppendEntity.
Благодарю, но если речь идёт о DeepClone, то при попытке добавить клона через blockTableRecord.AppendEntity(clonePolygon) в следующей строчке после using с объявлением этого самого клона у нас новое исключение за сегодня: eAlreadyInDb. По всей видимости, в базу данных всё же он смог проникнуть.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Lis,
Значить или Clone (и добавление в базу) или DeepCloneObjects и работа с клоном, который уже в базе.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение