将字典写入NOD会导致错误。
嘿帮,将 xrecord 写入 NOD 上的字典,代码似乎运行良好,字典是第一次通过创建的,xrecords似乎被正确地添加到其中。我正在使用锁定的事务,但是当我尝试保存时,我收到错误:此图形中的一个或多个对象无法保存为指定的格式。如果我在创建字典后审核绘图,则保存似乎可以正常工作,尽管没有发现任何错误。我想我错过了关闭一些东西,或者类似的东西。我的字典代码是:public static void AddXrecordToNamedDictionary(string dictionaryName, string key, Xrecord xRec)。{。
DBDictionary myDbDictionary = new DBDictionary();。
using (LockedTransaction tr = Active.Document.TransactionManager.StartLockedTransaction())。
{。
DBDictionary nod = tr.GetObject(HostApplicationServices.WorkingDatabase.NamedObjectsDictionaryId,。
OpenMode.ForWrite) as DBDictionary;。
如果(点头,包含(字典名称))。
{。
设置字典。
myDbDictionary = (DBDictionary)tr.GetObject(点头.GetAt(dictionaryName), OpenMode.ForWrite);。
}。
还。
{。
创建字典。
点头,SetAt(dictionaryName, myDbDictionary);。
断续器AddNewlyCreatedDBObject(myDbDictionary, true);。
}。
myDbDictionary.SetAt(key, xRec);。
断续器Commit();。
}。
}。
**** Hidden Message ***** 事实证明,问题不在于将新的 xrecord 添加到数据库事务中。更正代码:public static void AddXrecordToNamedDictionary(string dictionaryName, string key, Xrecord xRec)。
{。
DBDictionary myDbDictionary = new DBDictionary();。
using (LockedTransaction tr = Active.Document.TransactionManager.StartLockedTransaction())。
{。
DBDictionary nod = tr.GetObject(HostApplicationServices.WorkingDatabase.NamedObjectsDictionaryId,。
OpenMode.ForWrite) as DBDictionary;。
如果(点头,包含(字典名称))。
{。
设置字典。
myDbDictionary = (DBDictionary)tr.GetObject(点头.GetAt(dictionaryName), OpenMode.ForWrite);。
}。
还。
{。
创建字典。
点头,SetAt(dictionaryName, myDbDictionary);。
断续器AddNewlyCreatedDBObject(myDbDictionary, true);。
}。
添加 xrecord。
myDbDictionary.SetAt(key, xRec);。
断续器AddNewlyCreatedDBObject(xRec,true);//。
断续器Commit();。
}。
}。
优秀的结果!
您应该通过以下方式对此进行测试:在
添加记录后,在某个位置执行 UNDO 可能会导致记录被删除。这是一个错误(我猜,它可能是一个功能),可以通过尝试在添加密钥之前删除它来解决。
...
try {
myDbDictionary.Remove(key);
} catch (System.Exception) { }
myDbDictionary.SetAt(key, xRec);
...
DBDictionary:myDbDictionary=new dbdictional()
粗体代码不是好代码:为什么在确定没有现有词典之前创建词典?在下面的代码中,如果NOD具有所需的字典,则代码将变量“myDbDictionary”重新指向现有的字典(在转换中打开),并有效地将“newed”字典(以粗体代码行创建)保留在mometry中,而不进行适当处理
您应该:
数据库字典myDbDictionary=null
使用(transansaction…())
{
如果(nod.Contains(…)
myDbDictionary=[在事务中打开]
}
否则
{
myDbDictionary=new DbDictionary();//只在需要时创建dbdictional对象,实例将由事务处理
< 谢谢你的提示,huiz。我已经按照你的建议在一个try/catch中实现了移除,但我正在努力理解这个问题。如果记录已经被删除,我重新添加,会不会出问题?确实如此。SetAt抛出重复键的错误?是实现中的功能/缺陷,移除DBDictionary的方法?@n.yuan:但它是好代码,它编译!这意味着它是好的,对不对?!谢谢你的建议。您将看到我已经实现了它,我还将变量声明移到了using语句中。为了澄清,我的理解是初始化的变量在退出作用域后会被GC处理掉,因为它在事务中被使用,这是不正确的吗?当前版本: public static void addxrecordtonamedictionary(string dictionary name,string key,Xrecord xRec)。
{。
使用(LockedTransaction tr = Active,document . transaction manager . startlockedtransaction())。
{。
DBDictionary nod = tr,GetObject(HostApplicationServices,working database . NamedObjectsDictionaryId,。
打开模式,ForWrite)作为DBDictionary。
db dictionary mydb dictionary = null;。
如果(点头,包含(字典名))。
{。
//设置字典。
mydb dictionary =(db dictionary)tr,GetObject(点头,GetAt(dictionaryName),OpenMode。for write);。
}。
否则。
{。
//创建字典。
mydb dictionary = new db dictionary();。
点头,SetAt(dictionaryName,mydb dictionary);。
trAddNewlyCreatedDBObject(mydb dictionary,true);。
}。
。
//尝试删除记录以清除被窃听的已删除记录。
尝试一下。
{。
myDbDictionary,移除(键);。
}。
catch(异常){}。
。
//添加xrecord。
myDbDictionary,SetAt(key,xRec);。
trAddNewlyCreatedDBObject(xRec,true);。
trcommit();。
}。
}。
声明变量和创建类的实例不是一回事。创建类的实例的良好做法是只在需要时进行。
是的,通常情况下。NET类的实例将由运行时自动决定GCed(例如,我们的代码通常不需要显式调用Dispose())。然而,AutoCAD.NETAPI中的类不是纯. NET对象。它们是AutoCAD C/C++对象的. NET包装器。如果引用的对象不正确,GCed将取决于Dispose()是如何在. NET包装器中实现的,我们外部的大多数欧特克人都不知道。有很多关于if的讨论。在AutoCAD. NET API发布后的前几年,Dispose()需要调用或不调用,讨论仍然不时出现。普遍接受的方法是,您的代码创建的任何不受Transaction监管的对象都需要显式处理。您可以在“处置或不处置”主题中搜索本论坛和欧特克的讨论论坛。
页:
[1]