2010-03-24 67 views
2

我很好奇任何用於解決ORM方法中對象層次結構的解決方案(在本例中,使用實體框架4)。我正在通過一些關於EF4的文檔並嘗試將其應用於簡單的庫存跟蹤計劃。有可能的類型庫存落入如下:我該如何最好地解決這個對象類型heirachy?某種類型的枚舉層次結構?

庫存項目類型:

  • 硬件
    • PC
      • 桌面
      • 服務器
      • 筆記本
    • 附件
      • 輸入(鍵盤,掃描儀等)
      • 輸出(週一itors,打印機等)
      • 存儲(USB記憶棒,磁帶驅動器等)
      • 通信(網絡卡,路由器等)
  • 軟件

有什麼建議沒有在這樣的情況下處理枚舉?枚舉甚至是解決方案嗎?我並不想爲這樣一個相對簡單的實驗設置一個荒謬的規範化數據庫(例如InventoryType,InventorySubtype,InventoryTypeToSubtype等的表格)。即使沒有包含其他屬性或方法(除了理想情況下會有相關附件和軟件但可能超出範圍的PC類型),我並不想過度複雜化每個子類型的數據模型。

感覺就像應該有一個非常簡單,優雅的解決方案,但我不能把它放在手指上。任何幫助或意見讚賞!

回答

1

我覺得這需要一個複合的設計模式:http://www.dofactory.com/Patterns/PatternComposite.aspx

有類似的代碼:

class InventoryItem 
{ 
    public string Name { get; private set; } 
    public InventoryItem Parent { get; private set; } 
    public IList<InventoryItem> Children { get; private set; } 
} 

HTH。

+0

我從一開始就想要這樣的東西(沒有意識到它被認爲是一個「複合設計模式」)。我只是不確定在實踐中EF如何生成類。事實證明,對自引用類的支持非常簡單。我仍然需要尋找一種有效的方法來遍歷heirachy [例如:如果HasAncestry(CurrentCategory,「Hardware」)],但應該很容易。 – nathanchere 2010-03-31 02:16:29

+1

Perhaphs OfType <>可能會幫助你在EF - http://msdn.microsoft.com/en-us/library/bb399295.aspx – Sunny 2010-03-31 02:49:04

1

你可以使用一個類型層次...

public interface IInventoryType 
{ 
    string Name { get; } 
} 

public class Hardware : IInventoryType 
{ 
    public string Name { get { return "Hardware"; } } 

    public class PC : IInventoryType 
    { 
     public string Name { get { return "PC"; } } 

     public class Desktop : IInventoryType 
     { 
      public string Name { get { return "Desktop"; } } 
     } 

     public class Server : IInventoryType 
     { 
      public string Name { get { return "Server"; } } 
     } 
    } 
} 

然後與他們的合作會是這個樣子......

IInventoryType invType = new Hardware.PC.Server(); 

if (invType is Hardware.PC.Server) 
{ 
    Console.WriteLine("Yes!"); 
} 
else 
{ 
    Console.WriteLine("No!"); 
} 

雖然它會工作,我不知道這說得通。這很容易變得複雜而難以維護。

這可能更適合作爲數據存儲在數據庫中,並編寫代碼以通用方式處理數據,而不是以特定方式處理數據。

每次添加新類型時,都需要更改代碼,這並不理想。

1

您的問題的要點與ORM沒有多大關係,它只是一個如何爲您的需求建立良好關係模型的問題。你已經給出了自己的答案:如果你不想爲每個枚舉建立一個不同的表格,不要這樣做。對你的PC類型,你的附件類型等使用一個整數attribut,並將它映射到你的代碼中定義的枚舉。這樣,當你擴展你的一個枚舉時,你不需要改變數據庫中的任何東西(甚至沒有任何枚舉表中的數據)。

當然,有些情況下,將枚舉建模爲單獨的表格會付出代價。很顯然,當你必須存儲額外的數據給你枚舉(就像一個短名稱,一個長名稱,一個ID等等)。或者當你有不同的程序時,可能用不同的編程語言,這些都需要處理同一組枚舉。或者當用戶應該能夠擴展PC類型列表而不需要新版本的程序。

1

這很難說是「可笑的歸一化」 - 事實上,一個自引用表是足夠使用鄰接表模型保存在數據庫中的信息:

Categories (CategoryID, CategoryName, ParentCategoryID) 

凡在ParentCategoryID引用CategoryID同一張桌子。

這可以被映射到一個非常簡單的實體類:

public class Category 
{ 
    public string Name { get; set; } 
    public Category ParentCategory { get; set; } 
    public IList<Category> ChildCategories { get; set; } 
} 

真的所有你有做。如果您開始擁有非常深的/廣泛的層次結構,那麼您可能需要考慮性能的替代模型,但考慮到此處的示例,距離簡單鄰接列表不遠。

忘記枚舉 - 它們在這裏沒有意義。如果這是一個數據驅動的應用程序,那麼您幾乎肯定希望能夠在不更改代碼的情況下對類別列表進行更改,枚舉類型將要求您執行該代碼。