乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 120|回复: 7

创建块后,无法向块添加属性定义

[复制链接]

21

主题

58

帖子

3

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
142
发表于 2019-6-26 06:49:35 | 显示全部楼层 |阅读模式
在运行以下代码后尝试保存时,我收到错误“此图形中的一个或多个对象无法保存为指定格式”。
  1.         private void EnsureJobHasAllAttrbuteDefinitions()
  2.         {
  3.             Document thisDrawing = null;
  4.             BlockTable blockTable;
  5.             ObjectId jobDetailsBlockObjectId;
  6.             try
  7.             {
  8.                 thisDrawing = AutoCADUtility.GetDocument();
  9.                 using (Transaction transaction = thisDrawing.Database.TransactionManager.StartTransaction())
  10.                 {
  11.                     blockTable = transaction.GetObject(thisDrawing.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
  12.                     if (blockTable.Has(BlockNames.JobDetails))
  13.                     {
  14.                         jobDetailsBlockObjectId = blockTable[BlockNames.JobDetails];
  15.                         AddMissingAttribute(jobDetailsBlockObjectId, JobDetailsBlockAttribute.Contractor);
  16.                         AddMissingAttribute(jobDetailsBlockObjectId, JobDetailsBlockAttribute.Merchant);
  17.                         AddMissingAttribute(jobDetailsBlockObjectId, JobDetailsBlockAttribute.ProjectName);
  18.                         AddMissingAttribute(jobDetailsBlockObjectId, JobDetailsBlockAttribute.DrawingName);
  19.                         AddMissingAttribute(jobDetailsBlockObjectId, JobDetailsBlockAttribute.WideWalls);
  20.                         AddMissingAttribute(jobDetailsBlockObjectId, JobDetailsBlockAttribute.Depot);
  21.                     }
  22.                     transaction.Commit();
  23.                 }
  24.             }
  25.             catch (Exception ex)
  26.             {
  27.                 MessageBox.Show("Job.EnsureJobHasAllAttrbuteDefinitions : " + ex.Message, MessageHeadings.ExceptionError);
  28.             }
  29.         }
  30.         private void AddMissingAttribute(ObjectId jobDetailsBlockObjectId, string attributeName)
  31.         {
  32.             Document thisDrawing;
  33.             Transaction transaction;
  34.             AttributeDefinition attribute;
  35.             BlockTableRecord jobDetailsBlock;
  36.             bool attributeExists = false;
  37.             try
  38.             {
  39.                 thisDrawing = AutoCADUtility.GetDocument();
  40.                 transaction = thisDrawing.Database.TransactionManager.TopTransaction;
  41.                 jobDetailsBlock = transaction.GetObject(jobDetailsBlockObjectId, OpenMode.ForRead) as BlockTableRecord;
  42.                 if (jobDetailsBlock.HasAttributeDefinitions)
  43.                 {
  44.                     foreach (ObjectId entity in jobDetailsBlock)
  45.                     {
  46.                         DBObject entityObject = transaction.GetObject(entity, OpenMode.ForRead) as DBObject;
  47.                         if (entityObject is AttributeDefinition)
  48.                         {
  49.                             attribute = entityObject as AttributeDefinition;
  50.                             if (attribute.Tag == attributeName)
  51.                             {
  52.                                 attributeExists = true;
  53.                             }
  54.                         }
  55.                     }
  56.                 }
  57.                 if (attributeExists == false)
  58.                 {
  59.                     //If the attribute has not been found, add it
  60.                     attribute = new AttributeDefinition(new Point3d(0, 510, 0), "", attributeName, "", ObjectId.Null);
  61.                     attribute.Height = 0.5;
  62.                     attribute.Visible = false;
  63.                     attribute.Layer = "0";
  64.                     attribute.ColorIndex = 256;               //Color by layer
  65.                     jobDetailsBlock.UpgradeOpen();
  66.                     jobDetailsBlock.AppendEntity(attribute);
  67.                 }
  68.             }
  69.             catch (Exception ex)
  70.             {
  71.                 MessageBox.Show("Job.AddMissingAttribute : " + ex.Message, MessageHeadings.ExceptionError);
  72.             }
  73.         }

我这样做是因为我有额外的属性,我已经添加到一个块中,我需要确保较旧的图形使用这些属性更新这个块。

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

4

主题

219

帖子

4

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
238
发表于 2019-6-26 13:39:50 | 显示全部楼层
在我看来,在“AddMissingAttribute()”方法中,您错过了
事务。AddNewlyCreatedDBObject(属性,true)
在新属性定义附加到“jobDetailBlock”对象后。这就是为什么保存图形时会出现上述错误:新添加的属性定义未包含在事务中,因此无法保存。
回复

使用道具 举报

21

主题

58

帖子

3

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
142
发表于 2019-6-27 04:35:30 | 显示全部楼层
非常感谢,那太好了。
因此,当创建属性并将其添加到新的块表记录时,会有某种递归功能将所有新的工件添加到事务中,但当我们将它们单独添加到现有的块表记录时,这种情况不会发生。不错的不一致的设计,但我想这是意料之中的事。
请注意,我只是对AddNewlyCreatedDBObject方法中“Add”标志感到好奇,并发现了这个https://www.theswamp.org/index.php?topic=42055.0主题....那值得一笑。
回复

使用道具 举报

69

主题

875

帖子

15

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1146
发表于 2019-6-27 05:02:29 | 显示全部楼层
不,事务及其使用方式非常一致,所发生的情况是您正在使用AddMissingAttribute方法创建另一个内部事务,但没有使用该内部事务添加新的属性对象_或提交内部事务,因此它们不会“粘滞”。
hth
回复

使用道具 举报

21

主题

58

帖子

3

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
142
发表于 2019-6-27 07:13:55 | 显示全部楼层
与其说是交易的使用,不如说是交易。上述AddMissingAttribute例程中的AddNewlyCreatedObject方法,作为其在首先创建属性定义时的使用:
  1.         private ObjectId CreateEasiBaseBlock(EasiBaseProperties easiBaseProperties)
  2.         {
  3.             ObjectId blockId = ObjectId.Null;
  4.             Document thisDrawing;
  5.             BlockTable blockTable;
  6.             Transaction transaction;
  7.             Circle innerCircle;
  8.             Circle outerCircle;
  9.             AttributeDefinition attribute;
  10.             try
  11.             {
  12.                 thisDrawing = AutoCADUtility.GetDocument();
  13.                 transaction = thisDrawing.Database.TransactionManager.TopTransaction;
  14.                 blockTable = transaction.GetObject(thisDrawing.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
  15.                 using (BlockTableRecord blockTableRecord = new BlockTableRecord())
  16.                 {
  17.                     blockTableRecord.Name = BlockNames.EasiBase;
  18.                     // Insert the block near 0,0,0 but not on it
  19.                     blockTableRecord.Origin = new Point3d(0, 1000, 0);
  20.                     // Add inner circle to the block
  21.                     innerCircle = new Circle();
  22.                     innerCircle.Center = new Point3d(0, 1000, 0);
  23.                     innerCircle.Radius = 600;
  24.                     innerCircle.Layer = LayerNames.EasiBase;
  25.                     innerCircle.ColorIndex = 256;               //Color by layer
  26.                     blockTableRecord.AppendEntity(innerCircle);
  27.                     // Add inner circle to the block
  28.                     outerCircle = new Circle();
  29.                     outerCircle.Center = new Point3d(0, 1000, 0);
  30.                     outerCircle.Radius = 650;
  31.                     outerCircle.Layer = LayerNames.EasiBase;
  32.                     outerCircle.ColorIndex = 256;               //Color by layer
  33.                     blockTableRecord.AppendEntity(outerCircle);
  34.                     //Add the attributes
  35.                     attribute = new AttributeDefinition(new Point3d(0, 1800, 0), "", EasiBaseBlockAttribute.SiteRef, EasiBaseBlockAttribute.SiteRef, ObjectId.Null);
  36.                     attribute.Height = 80;
  37.                     attribute.Visible = true;
  38.                     attribute.Layer = LayerNames.EasiBase;
  39.                     attribute.ColorIndex = 256;               //Color by layer
  40.                     blockTableRecord.AppendEntity(attribute);
  41.                     attribute = new AttributeDefinition(new Point3d(100, 1000, 0), "", EasiBaseBlockAttribute.EasiBaseSizeId, "", ObjectId.Null);
  42.                     attribute.Height = 0.5;
  43.                     attribute.Visible = true;
  44.                     attribute.Layer = LayerNames.EasiBase;
  45.                     attribute.ColorIndex = 256;               //Color by layer
  46.                     blockTableRecord.AppendEntity(attribute);
  47.                     attribute = new AttributeDefinition(new Point3d(100, 999, 0), "", EasiBaseBlockAttribute.CoverLevel, "", ObjectId.Null);
  48.                     attribute.Height = 0.5;
  49.                     attribute.Visible = true;
  50.                     attribute.Layer = LayerNames.EasiBase;
  51.                     attribute.ColorIndex = 256;               //Color by layer
  52.                     blockTableRecord.AppendEntity(attribute);
  53.                     attribute = new AttributeDefinition(new Point3d(100, 998, 0), "", EasiBaseBlockAttribute.InvertLevel, "", ObjectId.Null);
  54.                     attribute.Height = 0.5;
  55.                     attribute.Visible = true;
  56.                     attribute.Layer = LayerNames.EasiBase;
  57.                     attribute.ColorIndex = 256;               //Color by layer
  58.                     blockTableRecord.AppendEntity(attribute);
  59.                     attribute = new AttributeDefinition(new Point3d(100, 997, 0), "", EasiBaseBlockAttribute.OverallPREDLReference, "", ObjectId.Null);
  60.                     attribute.Height = 0.5;
  61.                     attribute.Visible = true;
  62.                     attribute.Layer = LayerNames.EasiBase;
  63.                     attribute.ColorIndex = 256;               //Color by layer
  64.                     blockTableRecord.AppendEntity(attribute);
  65.                     attribute = new AttributeDefinition(new Point3d(100, 996, 0), "", EasiBaseBlockAttribute.MouldTypeId, "", ObjectId.Null);
  66.                     attribute.Height = 0.5;
  67.                     attribute.Visible = true;
  68.                     attribute.Layer = LayerNames.EasiBase;
  69.                     attribute.ColorIndex = 256;               //Color by layer
  70.                     blockTableRecord.AppendEntity(attribute);
  71.                     attribute = new AttributeDefinition(new Point3d(100, 995, 0), "", EasiBaseBlockAttribute.SteelRingDepthId, "", ObjectId.Null);
  72.                     attribute.Height = 0.5;
  73.                     attribute.Visible = true;
  74.                     attribute.Layer = LayerNames.EasiBase;
  75.                     attribute.ColorIndex = 256;               //Color by layer
  76.                     blockTableRecord.AppendEntity(attribute);
  77.                     attribute = new AttributeDefinition(new Point3d(100, 994, 0), "", EasiBaseBlockAttribute.NumberOfSeatingRings, "", ObjectId.Null);
  78.                     attribute.Height = 0.5;
  79.                     attribute.Visible = true;
  80.                     attribute.Layer = LayerNames.EasiBase;
  81.                     attribute.ColorIndex = 256;               //Color by layer
  82.                     blockTableRecord.AppendEntity(attribute);
  83.                     attribute = new AttributeDefinition(new Point3d(100, 993, 0), "", EasiBaseBlockAttribute.CoverSlabDepthId, "", ObjectId.Null);
  84.                     attribute.Height = 0.5;
  85.                     attribute.Visible = true;
  86.                     attribute.Layer = LayerNames.EasiBase;
  87.                     attribute.ColorIndex = 256;               //Color by layer
  88.                     blockTableRecord.AppendEntity(attribute);
  89.                     attribute = new AttributeDefinition(new Point3d(100, 992, 0), "", EasiBaseBlockAttribute.NumberOf250Rings, "", ObjectId.Null);
  90.                     attribute.Height = 0.5;
  91.                     attribute.Visible = true;
  92.                     attribute.Layer = LayerNames.EasiBase;
  93.                     attribute.ColorIndex = 256;               //Color by layer
  94.                     blockTableRecord.AppendEntity(attribute);
  95.                     attribute = new AttributeDefinition(new Point3d(100, 991, 0), "", EasiBaseBlockAttribute.NumberOf500Rings, "", ObjectId.Null);
  96.                     attribute.Height = 0.5;
  97.                     attribute.Visible = true;
  98.                     attribute.Layer = LayerNames.EasiBase;
  99.                     attribute.ColorIndex = 256;               //Color by layer
  100.                     blockTableRecord.AppendEntity(attribute);
  101.                     attribute = new AttributeDefinition(new Point3d(100, 990, 0), "", EasiBaseBlockAttribute.NumberOf750Rings, "", ObjectId.Null);
  102.                     attribute.Height = 0.5;
  103.                     attribute.Visible = true;
  104.                     attribute.Layer = LayerNames.EasiBase;
  105.                     attribute.ColorIndex = 256;               //Color by layer
  106.                     blockTableRecord.AppendEntity(attribute);
  107.                     attribute = new AttributeDefinition(new Point3d(100, 989, 0), "", EasiBaseBlockAttribute.NumberOf1000Rings, "", ObjectId.Null);
  108.                     attribute.Height = 0.5;
  109.                     attribute.Visible = true;
  110.                     attribute.Layer = LayerNames.EasiBase;
  111.                     attribute.ColorIndex = 256;               //Color by layer
  112.                     blockTableRecord.AppendEntity(attribute);
  113.                     attribute = new AttributeDefinition(new Point3d(100, 990, 0), "", EasiBaseBlockAttribute.EasiBaseId, "", ObjectId.Null);
  114.                     attribute.Height = 0.5;
  115.                     attribute.Visible = true;
  116.                     attribute.Layer = LayerNames.EasiBase;
  117.                     attribute.ColorIndex = 256;               //Color by layer
  118.                     blockTableRecord.AppendEntity(attribute);
  119.                     //Add the block to the record
  120.                     blockTable.UpgradeOpen();
  121.                     blockTable.Add(blockTableRecord);
  122.                     transaction.AddNewlyCreatedDBObject(blockTableRecord, true);
  123.                     blockId = blockTableRecord.Id;      
  124.                 }
  125.             }
  126.             catch (Exception ex)
  127.             {
  128.                 MessageBox.Show("EasiBase.CreateEasiBaseBlock : " + ex.Message, MessageHeadings.ExceptionError);
  129.             }
  130.             return blockId;
  131.         }

我希望看到块中的每个人工制品分别添加到事务中。这不是问题。我只是想理解其中的原因……嗯,在合理的范围内(我这样做不是为了好玩)。
回复

使用道具 举报

69

主题

875

帖子

15

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1146
发表于 2019-6-27 07:35:41 | 显示全部楼层
是的,我明白你的意思。
我猜
当一个块被创建/添加到db时,它会查找任何相关的属性记录,然后在通过当前事务添加块时一次将每个记录添加到属性表中。
回复

使用道具 举报

21

主题

58

帖子

3

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
142
发表于 2019-6-27 09:06:10 | 显示全部楼层
我怀疑数据库结构是这样的,理论上任何对象都可以是任何其他对象的子对象,而块、块引用和其他对象的结构是建立在其上的人工构造(有点像由解析器处理的语言的关键字)....因此这个方法递归地处理每个孩子(以及孩子的孩子,等等)。
无论如何,我已经完成了今天的学习,我将再次关闭我的大脑,继续我的工作。
回复

使用道具 举报

4

主题

219

帖子

4

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
238
发表于 2019-6-27 10:03:31 | 显示全部楼层

好吧,当您创建一个新的复合DBObject时,例如BlockTableRecord,或带有属性引用的BlockAudi,有两种方法可以将其添加到事务中:
1。您可以创建它的新实例,然后向它们添加子对象。然后您将复合对象添加/附加到数据库的适当所有者,您只需要将此复合对象添加到事务中,而不是其中的每个子对象。
2.您可以创建新的复合对象,将其添加/附加到DB中的适当所有者,然后将其添加到事务中(此时,新的复合对象已成为DB-驻留对象,但您仍然可以通过中止事务来重新跟踪,当然)。现在,您可以将子对象添加到复合对象中,如您所见,对于新添加的子对象,它们需要添加到事务中。
在创建新的复合对象时,使用方法1.将是最自然、最合乎逻辑的,但我确实看到代码不时使用方法2(包括我自己)。在您的情况下,由于您正在向现有的、驻留在DB中的复合对象(BlockTableRecord,这意味着当复合对象在事务中打开时,它本身和它中的所有子对象都在事务中)添加子对象(属性定义),因此您尝试添加的新对象必须添加到事务中(即方法2)。
我们可能会想(正如您所描述的),既然它已经在事务中,为什么欧特克不在添加/附加到复合对象时自动将新的子对象添加到事务中?好吧,考虑方法名称:AddNewlyCreatedDBObject(),它不仅将对象添加到事务中,还将它们标记为“新添加的”,这样如果您想回滚,只有新添加的对象才会从DB驻留的复合对象中删除。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2024-11-22 09:59 , Processed in 0.211081 second(s), 68 queries .

© 2020-2024 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表