2011-08-26 47 views
5

情況是,我有一個模型實體的表。該實體具有許多屬性(每個屬性都由表中的列標識)。事情是,在將來我需要添加新的屬性或刪除一些屬性。問題是如何建模數據庫和相應的代碼(使用C#),以便在出現這種情況時,只需「擁有」一個新屬性將非常簡單。泛型和數據庫 - 一個設計問題

在一開始只有一個屬性,所以我有一列。我在類中定義了相應的屬性,使用適當的類型和名稱,然後創建存儲過程來讀取並更新它。然後來到第二個屬性,快速複製粘貼,更改名稱和類型以及一些SQL,然後就是它了。顯然這不是一個合適的模式。在這個時候,你們中的一些人可能會建議一個ORM(EF或其他),因爲這會自動生成SQL和代碼,但現在這不是我的選擇。

我認爲只有一個讀取一個屬性(通過屬性名稱)和另一個更新它(通過名稱和值)的過程,然後一些通用程序讀取同一語句中的一個實體或一個實體的所有屬性。如果您考慮使用泛型,但在數據庫中不知道泛型,那麼在C#中聽起來很容易,所以不可能擁有強大的類型化解決方案。

我想有一個解決方案,「儘可能強類型」,所以我不需要做大量的轉換和解析。我會在代碼中定義可用的屬性,所以你不要猜測你有什麼可用的東西,並使用魔術字符串等。那麼在系統中添加一個新屬性的過程只會意味着在表中添加一個新列並在代碼中添加一個新的屬性「定義」(例如在一個枚舉中)。

+0

爲什麼你不能使用EF?微軟的天才們已經想出了這方面的知識,爲你做了很多工作。我不想看到你重新發明車輪。 – Jay

+0

是的,我不明白你爲什麼需要避免ORM。 (另外,我不知道C#泛型與這些有什麼關係) –

+0

我同意,但EF在架構方面稍微走了一些路,所以我現在還不能使用它。 – CyberDude

回答

2

這聽起來像你想這樣做:

MyObj x = new MyObj(); 
x.SomeProperty = 10; 

您有創建一個表,但是你不想保留改變該表時加

x.AnotherProperty = "Some String"; 

您需要正常化表格數據,如下所示:

-> BaseTable 
    RecordId, Col1, Col2, Col3 

-> BaseTableProperty 
    PropertyId, Name 

-> BaseTableValue 
    ValueId, RecordId, PropertyId, Value 

你的班級看起來像這樣:

public class MyObj 
{ 
     public int Id { get; set; } 
     public int SomeProperty { get; set; } 
     public string AnotherProperty { get; set; } 
} 

當您通過DL創建對象時,可以枚舉記錄集。然後編寫一次代碼,檢查屬性與您的配置同名(BaseTableProperty.Name == MyObj.<PropertyName> - 然後在枚舉記錄集時嘗試將類型轉換爲該類型

然後,只需將其他屬性添加到你的對象,另一個記錄到數據庫中BaseTableProperty,然後你可以存儲在BaseTableValue的那個傢伙值

例:

RecordId 
======== 
1 

PropertyId   Name 
==========   ==== 
1     SomeProperty 

ValueId  RecordId  PropertyId  Value 
=======  ========  ==========  ===== 
1   1    1    100 

你有兩個結果集,一個基本的數據,和一個加盟從Property和Value表中獲得。在列舉每條記錄時,您會看到名稱爲SomeProperty - 是否存在typeof(MyObj).GetProperty("SomeProperty")?是?它是什麼數據類型?詮釋?好了,然後嘗試通過設置屬性轉換成「100」,以int

propertyInfo.SetValue(myNewObjInstance, Convert.ChangeType(dbValue, propertyInfo.PropertyType), null); 

對於每個屬性。

+0

接近,但我並不真的想要或者不需要在課堂上申報每個屬性。很少發生我一次需要多個房產的情況。大多數情況下,我擁有對象ID,並且只需要知道其中一個屬性。這就是爲什麼我要有一個通用的'GetProperty(int objectID,string propertyName)'方法。 – CyberDude

+0

我會接受它,因爲它最接近我要採取的解決方案。 – CyberDude

0

即使你說你不能使用它們,這也是大多數ORM所做的。取決於你使用哪一個(或者如果是學習體驗,甚至可以創建),它們在複雜性和性能上會有很大的不同。如果你喜歡重量輕的ORM,請檢查Dapper.Net。它也使用泛型,因此您可以檢查代碼,瞭解其工作原理,並根據需要創建自己的解決方案。