2011-09-13 85 views
5

我有關於對象的視圖中的自定義字段的體系結構問題。假設您有一個用戶對象,其中包含一些基本信息,例如名字,姓氏......,可供所有客戶使用。代表對象的窗體的自定義字段

現在,我們經常得到的問題從客戶增加夫婦典型的域自定義字段。我們現在的解決方案是存儲鍵值對的xml數據列。到目前爲止,這一直是好的,但現在我們必須找到更多的架構解決方案。

例如,現在,客戶想要一個下拉在那裏可以選擇其自定義字段的值。我們仍然可以將選定的值存儲在xml數據列中,但我們在哪裏存儲所有這些下拉值...

我知道在sharepoint中,您還可以添加自定義字段,如下拉列表,並且我想知道如何處理這是最好的。我希望避免與90列(10鹼性,然後10爲每一個客戶),爲客戶創建自定義的表,或者具有桌子,...

你的想法,它應該是通用的,能夠應對未來的種種問題。

我在想是每個記錄都有一個外鍵的客戶(渠道在我們的數據庫)一表UserConfiguration,然後一列字段名,列的FieldType和列值。列值應該是xml類型列,因爲對於下拉列表,我們需要添加多個值。另外,每個值都可以附加額外的數據(不只是名稱)。另一個問題是如何存儲選定的值。我不喜歡在數據庫中使用外鍵到xml的想法(讀取Azure無法處理的所有內容)。你只是存儲值的名稱(如果值從xml中消失,該怎麼辦?)?

任何文檔,這類問題的鏈接也會很好。我試圖找到一種設計模式來處理數據庫中的這類問題。

+0

如果這是脫離主題,那麼你不是一個真正的生活程序員。 –

+1

你有沒有看到這個:因此:http://stackoverflow.com/questions/1126783/what-are-design-patterns-to-support-custom-fields-in-an-application?這個主題看起來很全面。 –

+0

@Simon Thx,還沒有找到。 –

回答

4

我想回答你的問題分爲兩個部分:
1)在數據庫服務器
2)限制自定義字段值的枚舉實現自定義字段


雖然1)中的常見解決方案在@Simon引用的question中進行了討論,但是您可能正在尋找關於問題是什麼以及它爲什麼尚未解決的討論。

  • 數據庫是很好的結構化,類型化數據
  • 自定義字段本質上是結構化程度較低
  • 因此,自定義字段更難在數據庫
  • 一些與工作或許多使用的優點數據庫丟失
    • 某些查詢可能會更加困難或不可能
    • 類型安全可能會丟失(在數據庫中)
    • 數據的完整性可能不再(由數據庫)
    • 強制執行它的執行者和維護者

正如other question討論了很多工作,也沒有完美的解決方案。
但是這些好處/功能仍然需要在某個地方實現,因此應用程序經常會對數據完整性和類型安全性負責。
對於像這樣的情況,人們創建了Object-Relation Mapping tools,但是,就像Jeff Atwood says一樣,即使使用ORM也會產生比解決問題更多的問題。然而,你提到它'應該是通用的並且能夠在將來處理各種問題' - 這使我認爲ORM可能是你最好的選擇。

因此,總結我的回答,這是已知解決方案的已知問題,其中沒有一個是完全滿意的(因爲它很難)。選擇你的毒藥。


要回答(我認爲是)你問題的第二部分:
作爲鏈接的問題,你可以在你的數據庫自定義字段實現Entity-Attribute-Value,然後添加一個額外的表來保存提及每個實體的合法價值。然後,EAV表的屬性/值是屬性值表中的外鍵。

例如,

CREATE TABLE `attribute_value` (-- enumerations go in this table 
    `attribute` varchar(30), 
    `value` varchar(30), 
    PRIMARY KEY (`attribute`, `value`) 
); 

CREATE TABLE `eav` (-- now the values of attributes are restricted 
    `entityid` int, 
    `attribute` varchar(30), 
    `value` varchar(30), 
    PRIMARY KEY (`entityid`, `attribute`), 
    FOREIGN KEY (`attribute`, `value`) REFERENCES `attribute_value`(`attribute`, `value`) 
); 

當然,這個解決方案是不完美的或完全的 - 它只是應該說明的想法。例如,它使用varchars,並且缺少type列。另外,誰可以決定每個屬性的可能值是什麼?這些可以隨時由用戶更改嗎?

2

我正在爲客戶做類似的事情。我創建了一個JSON FieldType,它包含複雜對象的全部JSON流以及包含我的C#模型類的FQTN(FullQualifiedTypeName)的String。

通過使用自定義的New-,Edit-和Display-Forms,我們確保了我們的自定義對象呈現最佳用戶體驗的正確方式。

爲了促進從複雜的C#模式向SharePoint列表領域,我們已經建立類似微軟InfoPath中一樣。用戶可以從Complex C#類型中選擇Properties或MetaData,該類型將自動提升到託管SharePoint列表。

JSON的一大優勢是,它比XML更小,更容易與在網絡世界。 (JavaScript的...)

2

當您讓用戶創建數據模型時,我建議您查看一個文檔數據庫或'NoSQL',因爲您完全想要的是存儲無模式數據結構。

此外,SHAREPOINT將元數據存儲你所提到的方式(10列文本,5日等)

這就是說,在我目前的項目(鎖定在SharePoint,所以框架3。5 + SQL Server和所有追隨我們使用如下幾分相似結構的約束):

Form 
Id 

Attribute (or Field) 
Name 
Type (enum) Text, List, Dates, Formulas etc 
Hidden (bool) 
Mandatory 
DefaultValue 
Options (for lists) 
Readonly 
Mask (for SSN etc) 
Length (for text fields) 
Order 

Metadata 
FormId 
AttributeId 
Text (the value for everything but dates) 
Date (the value for dates) 

我們的配方使用的功能,例如增加:INC([attribute1][attribute2], 6),這將產生類似000999的組合的第999次實例爲屬性1和屬性2爲一種形式的值,這被存儲爲:

AttributeIncrementFormula 
AtributeId 
Counter 
Token 

其他「公式」(又名任何非平凡的),諸如條形碼被存儲爲單個的元數據值。在實際應用中,我們有這樣的事情:以上

var form = formRepository.GetById(1); 
form.Metadata["firstname"].Value 

價值是決定我們是否應該從文本或日期值,如果一些額外的需要變換一個只讀屬性。請注意,這裏的數據庫僅僅是一個存儲,我們在應用程序中擁有所有的域複雜性。

我們也讓我們的客戶決定哪個屬性是表單標題,例如,如果firstname是表單標題,他們將設置跨越整個應用程序的內存參數,如Params.InMemory.TitleAttributeId = <user-defined-id>

我希望這能給你一些關於類似場景的生產impl的見解。

2

這實在是一個多回答一個評論,但我需要更多的空間比SO將使徵求意見,所以這裏的那朵:

我覺得你的UserConfiguration表的做法是好的,只是建議抽象「類型」和設計多一點的「價值」件:

  • 由於你的應用將需要驗證用戶輸入,「類型」的每個概念將具有相關聯的片評價邏輯的。顯然,您可以將更多的這些數據抽象成數據,這樣可以讓您的代碼變得更簡單。枚舉列表是一個好的開始,但是如果您的「驗證器」邏輯可以擴展爲處理文本字符串和布爾邏輯表達式的模式匹配(例如描述/強制執行輸入值的約束),那麼您可以表達幾乎任何「類型」您的應用程序可能需要處理的(相對)簡單的「原子」,您可以自然地映射到數據庫表。在存儲用戶指定的值時,可以將「原始」數據(例如以JSON格式)和外鍵存儲到關聯的「類型」中,也可以添加一個查找/緩存系統,該系統分配一個整數到系統遇到的每個新值(例如,可以通過檢查「原始」數據的散列來檢查「新穎性」)。後一種方法顯然可以更好地擴展,如果你期望有大量的數據重複(當然這是在多選菜單的情況下)。

相關問題