第一步:自定义事务对象
自定义事务对象
/// <summary>
/// 自定义事务
/// </summary>
public class DBTrans : IDisposable
{
#region 私有字段
private bool disposedValue;
private bool _commit;
/// <summary>
/// 事务栈
/// </summary>
private static readonly Stack<DBTrans> dBTrans = new Stack<DBTrans>();
#endregion
#region 公开属性
/// <summary>
/// 返回当前事务
/// </summary>
public static DBTrans Top => dBTrans.Peek();
/// <summary>
/// 事务管理器
/// </summary>
public Transaction Trans { get; private set; }
/// <summary>
/// UI应用
/// </summary>
public UIApplication UIApplication { get; private set; }
/// <summary>
/// 应用
/// </summary>
public Application Application { get; private set; }
/// <summary>
/// UI文档
/// </summary>
public UIDocument UIDocument { get; private set; }
/// <summary>
/// 文档
/// </summary>
public Document Document { get; private set; }
#endregion
#region 构造函数
/// <summary>
/// 默认构造函数,默认为打开当前文档,默认提交事务
/// </summary>
/// <param name="doc">要打开的文档</param>
/// <param name="commit">事务是否提交</param>
public DBTrans(Document doc, bool commit = true)
{
this.Document = doc;
this.UIApplication = new UIApplication(this.Document.Application);
this.UIDocument = this.UIApplication.ActiveUIDocument;
this.Application = this.UIApplication.Application;
Init(commit);
}
/// <summary>
/// 默认构造函数,默认为打开当前文档,默认提交事务
/// </summary>
/// <param name="doc">要打开的文档</param>
/// <param name="commit">事务是否提交</param>
public DBTrans(Document doc, string name, bool commit = true)
{
this.Document = doc;
this.UIApplication = new UIApplication(this.Document.Application);
this.UIDocument = this.UIApplication.ActiveUIDocument;
this.Application = this.UIApplication.Application;
Init(commit,name);
}
/// <summary>
/// 初始化事务及事务队列、提交模式
/// </summary>
/// <param name="commit">提交模式</param>
private void Init(bool commit,string name=null)
{
if (name == null) name = Guid.NewGuid().ToString("D");
Trans = new Transaction(Document,name);
Trans.Start();
_commit = commit;
dBTrans.Push(this);
}
#endregion
#region 获取元素
/// <summary>
/// 通过Id获取元素
/// </summary>
/// <typeparam name="T">元素类型</typeparam>
/// <param name="id">元素Id</param>
/// <returns>元素对象</returns>
public T GetElement<T>(ElementId id) where T : Element
{
return Document.GetElement(id) as T;
}
/// <summary>
/// 通过引用获取元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="reference"></param>
/// <returns></returns>
public T GetElement<T>(Reference reference) where T : Element
{
return Document.GetElement(reference) as T;
}
/// <summary>
/// 通过唯一Id获取元素对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="uniqueId"></param>
/// <returns></returns>
public T GetElement<T>(string uniqueId) where T : Element
{
return Document.GetElement(uniqueId) as T;
}
#endregion
#region idispose接口相关函数
/// <summary>
/// 事务回滚
/// </summary>
public void Abort()
{
Trans.RollBack();
}
/// <summary>
/// 事务提交
/// </summary>
public void Commit()
{
if (_commit)
{
Trans.Commit();
}
else
{
Abort();
}
}
/// <summary>
/// 事务处理
/// </summary>
/// <param name="disposing">是否处理</param>
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// 释放托管状态(托管对象)
Commit();
dBTrans.Pop();
if (Trans.IsValidObject)
{
Trans.Dispose();
}
}
// 释放未托管的资源(未托管的对象)并替代终结器
// 将大型字段设置为 null
disposedValue = true;
}
}
/// <summary>
/// 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
/// </summary>
~DBTrans()
{
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
Dispose(disposing: false);
}
/// <summary>
/// 事务处理
/// </summary>
public void Dispose()
{
// 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
#endregion
}
第二步:使用using关键字使用事务对象
使用自定义事务
/// <summary>
/// 扩展数据测试
/// </summary>
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class TSTCmd2 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uidoc = commandData.Application.ActiveUIDocument;
Document doc = uidoc.Document;
var temp = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
Wall el = doc.GetElement(temp) as Wall;
//定义事务对象
using (DBTrans dBTrans = new DBTrans(doc))
{
Ent ent = new Ent() { A = 10, B = "测试", D = new Dictionary<string, int>() { { "K1", 1 }, { "K2", 2 } }, L = new List<int>() { 1, 2 }};
el.SetEntity(EntityEx.Build<Ent>("扩展数据1", ent));
ent = new Ent() { A = 10, B = "测试2", D = new Dictionary<string, int>() { { "K1", 1 }, { "K2", 2 } }, L = new List<int>() { 1, 2 },E = new Dictionary<int, int>() {{ 1,1} ,{ 2,2} } };
el.SetEntity(EntityEx.Build<Ent>("扩展数据2", ent));
}
return Result.Succeeded;
}
}