2010-03-24 79 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; } 
} 

真的所有你有做。如果您开始拥有非常深的/广泛的层次结构,那么您可能需要考虑性能的替代模型,但考虑到此处的示例,距离简单邻接列表不远。

忘记枚举 - 它们在这里没有意义。如果这是一个数据驱动的应用程序,那么您几乎肯定希望能够在不更改代码的情况下对类别列表进行更改,枚举类型将要求您执行该代码。