2015-09-08 56 views
0

有一個.Net Autocad插件,其中WCF服務用於在Autocad外部的另一個進程上調用方法 。 Autocad實體包裝在自定義類中並通過WCF傳遞。一旦調用返回,插件需要將結果寫回Autocad數據庫。在Autocad .Net WCF插件中保留ObjectId引用

這是問題:需要ObjectId來獲取對象並將結果寫回; WCF序列化數據並且ObjectId不可序列化。所以我無法訪問該對象。

有沒有解決方法嗎?

回答

1
得到 objectId

您可以使用屬性ObjectId.OldIdPtr這是一個IntPtr(可序列化)。爲了讓您的ObjectId回來,只是做:

var id = new ObjectId(oldIdPtr); 

這比使用手柄一個更直接的方式(這需要一個查找)

+0

的確,它更容易。謝謝。 –

+0

謝謝Maxence。 ObjectId有許多其他參數(e.x數據庫)。一旦以這種方式創建ObjectId,它們是否仍然有效?我會嘗試。 – ali

+1

是的,ObjectId中唯一的狀態是指向他的非託管對象的指針。所有屬性都從非託管端檢索。 – Maxence

2

你必須序列化ObjectId的價值手柄,因爲它是不可序列:

[Serializable] 
public class TobeSerialized 
{ 
    private long idHandleValue; 
    [NonSerialized] 
    private ObjectId id; 

    public TobeSerialized() 
    { 
     this.idHandleValue = id.Handle.Value; 
    } 
public ObjectId GetObjectId(Database database, long handleValue) 
    { 
     Handle handle = new Handle(handleValue); 
     ObjectId id = database.GetObjectId(false, handle, 0); 
     return id; 
    } 
} 

然後,當你反序列化Class object,你將能夠通過調用方法GetObjectId(Database database, long handleValue)

+0

感謝Zimer的回答。我知道這個解決方法。但是我擔心大量的GetObjectId性能。這種方法實際上做了什麼?它會創建新的ObjectId還是在數據庫上查找它? – ali

+1

@ali:齊默是對的。實際上,我看不到這個插件是如何序列化其他實體的。它們也包含ObjectId。更何況他們沒有標記爲可序列化。然而,它們實現MarshalByRefObject,這意味着它們可以通過遠程處理髮送,但不是WCF(不是我所知)。我的猜測是他們要麼使用一些遠程魔術,要麼他們使用實體屬性的POCO表示。如果後者是這種情況,那麼他們正在按照齊默的建議行事。 – bjhuffine

+0

@ali:Btw ...句柄是文檔中的持久ID。 ObjectId是會話的臨時ID。所以它實際上是從會話的圖形數據庫中檢索會話的註冊ObjectId。代碼也必須考慮Handle是一個十六進制值的事實,所以使用這個... ObjectId oid = currentDB.GetObjectId(false,new Handle(Convert。ToInt64(句柄,16)),0); – bjhuffine

0

對於每一個實體的,你可以得到直接處理無中介(OBJECTID) 。 使用Entity.Handle屬性。 遠離autocad指南

數據庫對象中包含的每個對象都被分配了幾個唯一的ID。您可以訪問對象的唯一方式如下: 實體句柄 ObjectId 實例指針 最常用的方法是通過其對象ID訪問對象。如果您的項目同時使用COM互操作和受管.NET API,則對象ID工作良好。如果您創建自定義AutoLISP函數,則可能需要使用實體句柄。 句柄在AutoCAD會話之間持續存在,所以如果您需要將繪圖信息導出到稍後可能需要用來更新繪圖的外部文件,它們纔是訪問對象的最佳方式。數據庫中的對象的ObjectId僅在數據庫加載到內存時才存在。數據庫關閉後,分配給對象的對象ID不再存在,並且可能在下次打開數據庫時有所不同。