2012-01-27 66 views
1

我喜歡Dapper,Massive,PetaPoco等的「微觀」方法,並且我喜歡控制我們發送到數據庫的SQL,大部分時間比較簡單。我也喜歡和POCO合作,但是當處理一個有點靈活的模式設計時,你經常遇到麻煩:)用於具有半靈活模式設計的數據庫的ORM

假設我們有一個Person實體,它總是有以下屬性。

  • 編號
  • 名稱
  • 電子郵件
  • 電話

但在某些情況下,有可能會像

  • 附加屬性SpecialPhoneNumber
  • VeryCustomValue

我真的很喜歡POCO,它具有我們知道永久存在的共同屬性。但是讓其他人可以通過鍵/值集合進行訪問。

什麼是最好的方法?那麼所有提到的「微笑主義者」都支持這個嗎?我已經看過他們,但沒有發現他們有任何跡象,但也許我錯過了一些東西。

是否可以直接用SqlDataReader來做到這一點?或者在使用反射創建對象時,讀取數百行的性能會不好?提到的ORM似乎都做得很好,我猜測下面使用DataReader。

希望你能幫助:)

編輯:我也許應該提到的是,我們必須在應用程序體系結構的控制。這是一個ERP解決方案,允許個人客戶定製他們的應用程序和底層數據庫。在應用程序中添加字段會在數據庫中添加列。壞我!不使說清楚擺在首位

回答

1

Massive可以支持這一點,因爲它物化數據到ExpandoObject的:

的祕訣是ExpandoObject。所有進入的產品和 Massive出品的所有東西都是一款Expando - 它可以讓你 做任何你想做的事情。在它的核心,一個ExpandoObject是 只是一個IDictionary <字符串,對象>

ExpandoObject實現IDictionary<string, Object>IEnumerable<KeyValuePair<string, Object>>,所以你可以枚舉和測試在你需要的任何方式成員。

Massive的默認設置是發出一個SELECT *查詢,所以ExpandoObject將包含表中的所有字段,甚至包括那些你不知道的信息。

您可以獲得Massive's current code from Github

Dapper也可以選擇爲動態對象,但與Massive不同,它只能選擇數據,不能插入,更新或刪除它。編輯:審查Dapper文檔,它似乎可以執行修改,因爲它可以執行任何SQL。有some more recent information about performing inserts with Dapper

+0

哇「也可以選擇爲動態對象,但與Massive不同,它只能選擇數據,不能插入,更新或刪除它。」沒有什麼比真相更遠了。 – 2012-01-31 02:43:18

+0

@SamSaffron:我不使用Dapper,我想我在回想起最初發布時只選擇了數據。當我將Dapper添加到這個答案時,我檢查了文檔,從我可以告訴的情況來看,情況依然如此。我現在看到它可以簡單地執行任何sql,但是在doc頁面中有點模糊。我已經編輯了我的答案,正在考慮您的意見。 – 2012-01-31 03:10:40

+0

它確實插入很好,從doco:http://code.google.com/p/dapper-dot-net/「執行一個不返回結果的命令 public static int Execute(this IDbConnection cnn,string sql, object param = null,SqlTransaction transaction = null)「..另請參閱:http://samsaffron.com/archive/2012/01/16/that-annoying-insert-problem-getting-data-into-the-db- using-dapper我正致力於改進Dapper標記wiki,但這個過程很慢 – 2012-01-31 03:18:04

-2

ID名稱電子郵件電話 但在某些情況下,可能會有額外的屬性,如 SpecialPhoneNumber VeryCustomValue

發送建築師回學校程序員設計的101錯誤 - Phone,SpecialPhoneNumber都不是Person的屬性(它不是Person,而是「Entity」,因爲它也可以是法律實體)。

他們是「接觸點」或其他東西的列表。

也就是說,屬性桶也可以在ORM中演示,但性能不好,但嘿,這是sql數據庫的工作方式。財產桶性能不佳。

+1

這只是一個例子來說明有自定義屬性。我們也無法控制底層架構:) – 2012-01-27 19:20:39

+0

壞例子的問題是他們回來傷害你。如果你不能拿出一個好榜樣,那麼你不瞭解問題或者很好地準備好問題。無法控制底層架構意味着沒有ORM - 無論如何你都陷入了痛苦的境地。 – TomTom 2012-01-27 19:22:02

+0

我不同意沒有任何控制意味着您必須求助於使用普通的舊類型的無類型數據集,如果這就是您的意思。 – 2012-01-27 19:25:49

0

在設計中爲每種類型的繼承或擴展表使用表格以允許在實體上添加數據。

+0

但是,如果你沒有選擇在「編譯」時執行此操作,但在API中需要一定的靈活性。爲了讓您獲得您可能事先不知道的顯示值? – 2012-01-27 19:28:05

+0

@ChristianSparre,所以你在運行時改變你的* DB *模式? – 2012-01-27 20:27:19

+1

@JoshC .:我認爲OP的場景是他的代碼必須針對數據庫的多個安裝運行 - 每個安裝都可能是通過添加無法在編譯時知道的字段進行定製的,並且將不同於安裝到安裝。 – 2012-01-27 20:44:43

0

MyBatis.NET(以前稱爲iBatis.NET)是一個數據映射工具,具有我覺得非常有用的功能。如果你從來沒有聽說過它,它是一個ORM工具,它允許你編寫SQL,並創建域對象,並使用XML將數據庫列映射到域對象屬性。

其中一個結果映射可能看起來像:

<resultMap id="Contact" class="Contact" > 
    <result property="ContactId" column="ContactId" /> 
    <result property="FirstName" column="FirstName" /> 
    <result property="MiddleInitial" column="MiddleInitial" /> 
    <result property="LastName" column="LastName" /> 
</resultMap> 

在有你有一個id爲結果,一類別名(它映射到Namespace.Folder.Contact,例如),和一個列表列屬性映射。

你可能有興趣的地方在於它有能力擴展結果地圖,就像你從類繼承一樣。在你的情況,你可能有:

<resultMap id="Person" class="Person" > 
    <result property="Id" column="Id" /> 
    <result property="Name" column="Name" /> 
    <result property="Email" column="Email" /> 
    <result property="Phone" column="Phone" /> 
</resultMap> 

併爲您的其他情況:

<resultMap id="PersonExtended" extends="Person" class="Person"> 
    <!-- inherits all the "Person" result map properties --> 
    <result property="SpecialPhoneNumber" column="SpecialPhoneNumber" /> 
    <result property="VeryCustomValue" column="VeryCustomValue" /> 
</resultMap> 

然後,你將有兩個單獨的查詢,一個選擇僅僅是基本的信息和地圖的「人「結果圖和另一個映射到包含更多列的」PersonExtended「結果圖的查詢。

還支持選擇字典和避免N + 1選擇。只是要注意:我不屬於MyBatis項目,我剛剛發現它非常靈活,並且是一個非常穩固的數據映射器。我將它用於我的所有項目,主要是因爲我編寫了一個工具,只需將它指向數據庫即可生成我的整個數據訪問層。

設置它有點PITA,但也許它可以爲你工作!