2011-02-11 131 views
3

我們有一個類庫,確實類似於ORM的一些基本操作,基本可以做這樣的事情:有沒有辦法避免FieldAccessException?

conn.Query<EntityType>("select * from table"); 

,並得到一個List<EntityType>。由於從列名到實體類型屬性的映射存儲在實體類型內部,因此當我們只需要一部分屬性時,我們可以輕鬆構建基本對象。

問題是,這段代碼在很大程度上依賴於反射,我們剛剛發現,我們知道我們的開銷比我們預期的要大得多。

例相關的各種操作的定時 「選擇表*」:

  1. 的IDataReader,通過所有的行循環,178ms
  2. 的IDataReader,呼叫的GetValues來獲取對象[]數組,對於所有行,260ms
  3. 的IDataReader,打電話的GetValues,構建新的對象,然後添加到列表中,所有行,356ms
  4. 的IDataReader,打電話的GetValues,構建新的對象,使用反射值複製到性能,1〜 0.500ms(29X第3步

我們緩存所涉及的反射,但仍然有太多的開銷。

由於涉及到的對象的99%與(1個或2支持字段)簡單屬性,以爲可以只是產生通過IL/DynamicMethod的以下代碼:

instance._Id = (int)value; 

此失敗,FieldAccessException,和我認爲這是因爲這些字段是私人的。有沒有什麼方法可以讓我生成這些代碼,或者我只是在安全方面大肆渲染錯誤的樹?

回答

5

是;在你DynamicMethod你需要告訴它本身與EntityType關聯;然後接入問題消失使用,設置ownertypeof(EntityType)過載,並skipVisibilitytrue

不過。 ,在大多數情況下,你應該能夠像田野一樣迅速地進入房產。所以,除非有充分的理由選擇田地,否則更喜歡這些屬性。當然,如果使用屬性,你可以讓用戶決定,通過裝飾最合適。

0

爲什麼不讓屬性讀/寫並調用「set property」方法而不是直接寫入備份屬性?

這也有,如果使用的實現類自動生成的屬性優勢(例如字符串名稱{;設置;}那麼你的代碼生成解決方案仍然有效,因爲它沒有就如何將任何假設物業實現

+0

現在我正在創建動態方法,它將使用屬性,但實體對象已生成,因此我們可以輕鬆地添加屬性,告訴反射生成器可以安全地訪問這些字段以獲得額外的性能。由於超過90%的應用程序在性能方面受數據庫流量的限制,因此我們現在將重點放在嘗試減少此區域的開銷。 – 2011-02-11 10:56:43

相關問題