(它涉及通过一个参数传递“活动”事务)
Function main()
...
Using Transaction tr = db.TransactionManager.StartTransaction()
Dim DbObjectCollection blocks = get_blocks(db, tr)
sort_blocks(blocks)
...
End Using
End Function
Function get_Blocks(db As Database, tr as Transaction) As DbObjectCollection
If tr == null Then throw new ArgumentNullException( "Function called outside the scope of transaction" )
...get blocks
End Function
话又说回来,熟练使用事务通过参数接收事务的每个方法可能不是那么可取的。
*编辑*
使用事务 tr = db。TransactionManager.StartTransaction()
我显然说:
Dim Transaction tr = db。TransactionManager.TopTransaction
*/EDIT*
看起来更容易接受 首先
欢迎来到沼泽伯特
您使用的是垂直命令吗?因为我记得Will使用的是MEP或其他不同的命令,但他发现它会为每个自定义命令创建一个事务
此外,任何需要或希望使用事务的方法都不需要传递事务
如果您后退一步查看,AutoCAD将执行您的代码的入口点只有这么多。
-初始化
-命令
—事件
-,否决
,等等,
并可以更改需要处理的方式
如果不注意使用嵌套或大量事务,则只能部分更改数据
需要休息一下,但当更好地了解需求时,有人可以帮助重构代码,以及如何在一个事务中封装方法。
感谢杰夫的欢迎!
你用我用“垂直”是什么意思?
如前所述,我的代码确实早就应该进行一些重构了。
我听从了WILL HATCH的建议,将所有操作都保留在1笔交易中。
这花了一些工作,但结果如下:
Sub Main()
' Get the current document and database
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
' Lock the document
Using acLckDoc As DocumentLock = acDoc.LockDocument()
' Start a transaction
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
Call function1()
dim obj as DbObject = function2()
If TypeOf (obj) Is BlockReference Then
Call function3(obj)
end if
' Save the changes
acTrans.Commit()
End Using ' Transaction
End Using ' Lock
End Sub
Function method1()
' Get the current document and database
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
Dim acTrans As Transaction = db.TransactionManager.TopTransaction
Dim blkTable As BlockTable = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
If blkTable.Has(_blockName) Then
......
End If
End Function
Function method2() as DBObject
' Get the current document and database
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
Dim acTrans As Transaction = db.TransactionManager.TopTransaction
Dim pPtOpts As PromptEntityOptions = New PromptEntityOptions("")
' Prompt for the start point
pPtOpts.Message = vbLf & _prompt
pPtOpts.AllowNone = False
Dim pPtRes As PromptEntityResult = acDoc.Editor.GetEntity(pPtOpts)
' Exit if the user presses ESC or cancels the command
If pPtRes.Status = PromptStatus.Cancel Then Return Nothing
Return acTrans.GetObject(pPtRes.ObjectId, OpenMode.ForRead)
End Function
sub method3(_blkRef as BlockReference)
' Get the current document and database
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
Dim acTrans As Transaction = db.TransactionManager.TopTransaction
Dim attCol As AttributeCollection = _blkRef.AttributeCollection
For Each attId As ObjectId In attCol
Dim attRef As AttributeReference = DirectCast(acTrans.GetObject(attId, OpenMode.ForWrite), AttributeReference)
Dim recievedValue As String = get_AttVal(attRef.Tag, _attVals)
If Not String.IsNullOrEmpty(recievedValue) Then attRef.TextString = recievedValue
Next
End sub
目前我遇到了与管理大量事务,管理单个事务完全相反的麻烦:
我正在左右回避以下错误:
“由于对象的当前状态,操作无效。
我有代码想要在同一事务的早期打开ForRead的对象上Allready已经准备好打开ForRead/Write。
也许我正在使这种方式变得复杂?
通过垂直,我的意思是
Civil3D,Autocad Arch,AutoCAD MEP等。添加到 AutoCAD 或扩展 AutoCAD 的产品。
必须找到一份工作,但稍后会发布一些东西,或者其他人会发布更好的东西。
不,我是在100%纯AutoCAD背景下编写.NET的
替换我在过去5年为我工作的公司编写的400页VBA代码。(不要问)
页:
1
[2]