Real_King 发表于 2015-6-11 22:30:35

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

本帖最后由 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 事务版↓(会报错)private void button1_Click(object sender, EventArgs e)
    {
      ObjectIdCollection acObjIdColl = new ObjectIdCollection();

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

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

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

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

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

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

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

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

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

      // 解锁文档   Unlock the document
      }

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

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

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

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

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

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

      // 解锁文档   Unlock the document
      }

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

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

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

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

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

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

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

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

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

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

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

      // 解锁文档   Unlock the document
      }

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

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

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

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

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

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

      // 解锁文档   Unlock the document
      }

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

    }   

雪山飞狐_lzh 发表于 2015-6-12 09:33:47

Openclosetr应该是有局限的吧

Real_King 发表于 2015-6-12 09:55:43

本帖最后由 Real_King 于 2015-6-12 10:01 编辑

雪山飞狐_lzh 发表于 2015-6-12 09:33 static/image/common/back.gif
Openclosetr应该是有局限的吧
而且发现,用openclosetr打断的实体,做选择集时结果有误,这下把我弄怕了,算了,还是全部用tr好了...老老实实的不折腾。
目前也没找到资料具体确定openclosetr的局限性体现在哪些方面,真不敢随便用。不过我觉得openclosetr处理时,实体的状态不是简单的write或read...实体objectid会发生意想不到的情况。thanks brother flyingfox
页: [1]
查看完整版本: 是bug吗?OpenCloseTransaction 与 Transaction 在此段代码的区别?