明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1154|回复: 2

是bug吗?OpenCloseTransaction 与 Transaction 在此段代码的区别?

[复制链接]
发表于 2015-6-11 22:30 | 显示全部楼层 |阅读模式
本帖最后由 Real_King 于 2015-6-11 22:39 编辑

图形数据库间复制对象,单击自己做的一个工具栏上的按钮后显示一个Form,实例化后直接show()的,
因为发现用模态对话框无法新建图形dwg.然后单击botton1,

使用
using (OpenCloseTransaction acTrans = acCurDb.TransactionManager.StartOpenCloseTransaction())
作为事务时,会报错eWasOpenForRead(如果acBlkTblRecNewDoc的OpenMode是write就报错write,
反正就是会报错)

而换做Transaction作为事务后
using (Transaction acTrans = acDbNewDoc.TransactionManager.StartTransaction())
运行无误。

自己写的代码是这样的情况,又用了.NET 开发人员手册上两图形数据库间复制圆的代码测试。

下面测试代码来自.NET 开发人员手册,画两个圆再新建个dwg复制过去.
在这儿我把两种事务的代码都列出,仅仅事务的定义不同,其它都相同。

CAD是10的版本,是bug吗?OpenCloseTransaction 与 Transaction 在此段代码的区别?
或者说,跟Form的显示方式(show、ShowModalDialog等等)有关?

OpenCloseTransaction 的效率比 Transaction 好,NET开发基础与实例第二版建议在读写实体对象
时尽量使用它,我刚刚换了CAD10做开发就兴冲冲全给用上了,结果就发现了这个问题,难道,
这会是bug吗?请各位Doctor have a look at,please! thanks in advance

被CAD06的bug弄怕了,好不容易能用10开发,这才刚刚用了一天...泪奔

OpenCloseTransaction 事务版↓(会报错)
  1. private void button1_Click(object sender, EventArgs e)
  2.     {
  3.       ObjectIdCollection acObjIdColl = new ObjectIdCollection();

  4.       // 获得当前文档和数据库   Get the current document and database
  5.       Document acDoc = AcadApp.DocumentManager.MdiActiveDocument;
  6.       Database acCurDb = acDoc.Database;

  7.       // 锁定当前图形   Lock the current document
  8.       using (DocumentLock acLckDocCur = acDoc.LockDocument())
  9.       {
  10.         // 启动一个事务  Start a transaction
  11.         using (OpenCloseTransaction acTrans = acCurDb.TransactionManager.StartOpenCloseTransaction())
  12.         {
  13.           // 以只读方式打开块表记录   Open the Block table record for read
  14.           BlockTable acBlkTbl;
  15.           acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
  16.                                        OpenMode.ForRead) as BlockTable;

  17.           // 以写方式打开模型空间块表记录   Open the Block table record Model space for write
  18.           BlockTableRecord acBlkTblRec;
  19.           acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
  20.                                           OpenMode.ForWrite) as BlockTableRecord;

  21.           // 创建一个圆心为(0,0,0),半径为 5 的圆    Create a circle that is at (0,0,0) with a radius of 5
  22.           Circle acCirc1 = new Circle();
  23.           acCirc1.SetDatabaseDefaults();
  24.           acCirc1.Center = new Point3d(0, 0, 0);
  25.           acCirc1.Radius = 5;

  26.           // 添加新对象到块表记录和事务中   Add the new object to the block table record and the transaction
  27.           acBlkTblRec.AppendEntity(acCirc1);
  28.           acTrans.AddNewlyCreatedDBObject(acCirc1, true);

  29.           // 创建一个圆心为(0,0,0),半径为 7 的圆   Create a circle that is at (0,0,0) with a radius of 7
  30.           Circle acCirc2 = new Circle();
  31.           acCirc2.SetDatabaseDefaults();
  32.           acCirc2.Center = new Point3d(0, 0, 0);
  33.           acCirc2.Radius = 7;

  34.           // 添加新对象到块表记录和事务中   Add the new object to the block table record and the transaction
  35.           acBlkTblRec.AppendEntity(acCirc2);
  36.           acTrans.AddNewlyCreatedDBObject(acCirc2, true);

  37.           // 添加所有要复制的对象到新的文档中    Add all the objects to copy to the new document
  38.           acObjIdColl = new ObjectIdCollection();
  39.           acObjIdColl.Add(acCirc1.ObjectId);
  40.           acObjIdColl.Add(acCirc2.ObjectId);

  41.           // 保存新对象到数据库中   Save the new objects to the database
  42.           acTrans.Commit();
  43.         }

  44.         // 解锁文档   Unlock the document
  45.       }

  46.       // 修改文件和路径以匹配你工作站中的图形模板     Change the file and path to match a drawing template on your workstation
  47.       string sLocalRoot = AcadApp.GetSystemVariable("LOCALROOTPREFIX") as string;
  48.       string sTemplatePath = sLocalRoot + "Template\\acad.dwt";

  49.       // 创建新的图形用于复制对象    Create a new drawing to copy the objects to
  50.       DocumentCollection acDocMgr = AcadApp.DocumentManager;
  51.       Document acNewDoc = acDocMgr.Add(sTemplatePath);
  52.       Database acDbNewDoc = acNewDoc.Database;

  53.       // 锁定新文档    Lock the new document
  54.       using (DocumentLock acLckDoc = acNewDoc.LockDocument())
  55.       {
  56.         // 在新数据库中启动事务   Start a transaction in the new database
  57.         using (OpenCloseTransaction acTrans = acDbNewDoc.TransactionManager.StartOpenCloseTransaction())
  58.         {
  59.           // 以只读方式打开块表   Open the Block table for read
  60.           BlockTable acBlkTblNewDoc;
  61.           acBlkTblNewDoc = acTrans.GetObject(acDbNewDoc.BlockTableId,
  62.                                              OpenMode.ForRead) as BlockTable;

  63.           // 以只读方式打开模型空间的块表记录    Open the Block table record Model space for read
  64.           BlockTableRecord acBlkTblRecNewDoc;
  65.           acBlkTblRecNewDoc = acTrans.GetObject(acBlkTblNewDoc[BlockTableRecord.ModelSpace],
  66.                                               OpenMode.ForRead) as BlockTableRecord;

  67.           // 复制对象到新的数据库中    Clone the objects to the new database
  68.           IdMapping acIdMap = new IdMapping();
  69.           acCurDb.WblockCloneObjects(acObjIdColl, acBlkTblRecNewDoc.ObjectId, acIdMap,
  70.                                      DuplicateRecordCloning.Ignore, false);

  71.           // 保存复制的对象到数据库中    Save the copied objects to the database
  72.           acTrans.Commit();
  73.         }

  74.         // 解锁文档   Unlock the document
  75.       }

  76.       // 设置新文档为当前文档   Set the new document current
  77.       acDocMgr.MdiActiveDocument = acNewDoc;

  78.     }   
Transaction 事务版↓
  1. private void button1_Click(object sender, EventArgs e)
  2.     {
  3.       ObjectIdCollection acObjIdColl = new ObjectIdCollection();

  4.       // 获得当前文档和数据库   Get the current document and database
  5.       Document acDoc = AcadApp.DocumentManager.MdiActiveDocument;
  6.       Database acCurDb = acDoc.Database;

  7.       // 锁定当前图形   Lock the current document
  8.       using (DocumentLock acLckDocCur = acDoc.LockDocument())
  9.       {
  10.         // 启动一个事务  Start a transaction
  11.         using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  12.         {
  13.           // 以只读方式打开块表记录   Open the Block table record for read
  14.           BlockTable acBlkTbl;
  15.           acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
  16.                                        OpenMode.ForRead) as BlockTable;

  17.           // 以写方式打开模型空间块表记录   Open the Block table record Model space for write
  18.           BlockTableRecord acBlkTblRec;
  19.           acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
  20.                                           OpenMode.ForWrite) as BlockTableRecord;

  21.           // 创建一个圆心为(0,0,0),半径为 5 的圆    Create a circle that is at (0,0,0) with a radius of 5
  22.           Circle acCirc1 = new Circle();
  23.           acCirc1.SetDatabaseDefaults();
  24.           acCirc1.Center = new Point3d(0, 0, 0);
  25.           acCirc1.Radius = 5;

  26.           // 添加新对象到块表记录和事务中   Add the new object to the block table record and the transaction
  27.           acBlkTblRec.AppendEntity(acCirc1);
  28.           acTrans.AddNewlyCreatedDBObject(acCirc1, true);

  29.           // 创建一个圆心为(0,0,0),半径为 7 的圆   Create a circle that is at (0,0,0) with a radius of 7
  30.           Circle acCirc2 = new Circle();
  31.           acCirc2.SetDatabaseDefaults();
  32.           acCirc2.Center = new Point3d(0, 0, 0);
  33.           acCirc2.Radius = 7;

  34.           // 添加新对象到块表记录和事务中   Add the new object to the block table record and the transaction
  35.           acBlkTblRec.AppendEntity(acCirc2);
  36.           acTrans.AddNewlyCreatedDBObject(acCirc2, true);

  37.           // 添加所有要复制的对象到新的文档中    Add all the objects to copy to the new document
  38.           acObjIdColl = new ObjectIdCollection();
  39.           acObjIdColl.Add(acCirc1.ObjectId);
  40.           acObjIdColl.Add(acCirc2.ObjectId);

  41.           // 保存新对象到数据库中   Save the new objects to the database
  42.           acTrans.Commit();
  43.         }

  44.         // 解锁文档   Unlock the document
  45.       }

  46.       // 修改文件和路径以匹配你工作站中的图形模板     Change the file and path to match a drawing template on your workstation
  47.       string sLocalRoot = AcadApp.GetSystemVariable("LOCALROOTPREFIX") as string;
  48.       string sTemplatePath = sLocalRoot + "Template\\acad.dwt";

  49.       // 创建新的图形用于复制对象    Create a new drawing to copy the objects to
  50.       DocumentCollection acDocMgr = AcadApp.DocumentManager;
  51.       Document acNewDoc = acDocMgr.Add(sTemplatePath);
  52.       Database acDbNewDoc = acNewDoc.Database;

  53.       // 锁定新文档    Lock the new document
  54.       using (DocumentLock acLckDoc = acNewDoc.LockDocument())
  55.       {
  56.         // 在新数据库中启动事务   Start a transaction in the new database
  57.         using (Transaction acTrans = acDbNewDoc.TransactionManager.StartTransaction())
  58.         {
  59.           // 以只读方式打开块表   Open the Block table for read
  60.           BlockTable acBlkTblNewDoc;
  61.           acBlkTblNewDoc = acTrans.GetObject(acDbNewDoc.BlockTableId,
  62.                                              OpenMode.ForRead) as BlockTable;

  63.           // 以只读方式打开模型空间的块表记录    Open the Block table record Model space for read
  64.           BlockTableRecord acBlkTblRecNewDoc;
  65.           acBlkTblRecNewDoc = acTrans.GetObject(acBlkTblNewDoc[BlockTableRecord.ModelSpace],
  66.                                               OpenMode.ForRead) as BlockTableRecord;

  67.           // 复制对象到新的数据库中    Clone the objects to the new database
  68.           IdMapping acIdMap = new IdMapping();
  69.           acCurDb.WblockCloneObjects(acObjIdColl, acBlkTblRecNewDoc.ObjectId, acIdMap,
  70.                                      DuplicateRecordCloning.Ignore, false);

  71.           // 保存复制的对象到数据库中    Save the copied objects to the database
  72.           acTrans.Commit();
  73.         }

  74.         // 解锁文档   Unlock the document
  75.       }

  76.       // 设置新文档为当前文档   Set the new document current
  77.       acDocMgr.MdiActiveDocument = acNewDoc;

  78.     }   
发表于 2015-6-12 09:33 来自手机 | 显示全部楼层
Openclosetr应该是有局限的吧
 楼主| 发表于 2015-6-12 09:55 | 显示全部楼层
本帖最后由 Real_King 于 2015-6-12 10:01 编辑
雪山飞狐_lzh 发表于 2015-6-12 09:33
Openclosetr应该是有局限的吧

而且发现,用openclosetr打断的实体,做选择集时结果有误,这下把我弄怕了,算了,还是全部用tr好了...老老实实的不折腾。
目前也没找到资料具体确定openclosetr的局限性体现在哪些方面,真不敢随便用。不过我觉得openclosetr处理时,实体的状态不是简单的write或read...实体objectid会发生意想不到的情况。thanks brother flyingfox
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-6 22:27 , Processed in 0.965874 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表