我如何最好地解决这个对象类型层次结构?某种枚举层次结构?

发布于 2024-08-26 17:15:03 字数 892 浏览 5 评论 0原文

我很好奇是否有任何解决方案可以在 ORM 方法中解决对象层次结构(在本例中,使用实体框架 4)。我正在研究 EF4 上的一些文档,并尝试将其应用于简单的库存跟踪程序。库存可能属于的类型如下:

库存项目类型:

  • 硬件
    • 电脑
    • 电脑
      • 桌面
      • 服务器
      • 笔记本电脑
    • 配件
      • 输入(键盘、扫描仪等)
      • 输出(显示器、打印机等)
      • 存储(U 盘、磁带驱动器等)
      • 通信(网卡、路由器等)
  • 软件

在这种情况下处理枚举有哪些建议?枚举是解决方案吗?我真的不想为这样一个相对简单的实验建立一个可笑的标准化数据库(例如 InventoryType、InventorySubtype、InventoryTypeToSubtype 等的表)。我真的不想让我的数据模型变得过于复杂,即使没有包含其他属性或方法,每个子类型都会被继承(除了 PC 类型,理想情况下会有相关的附件和软件,但这可能超出了这里的范围)。

感觉应该有一个非常简单、优雅的解决方案,但我无法具体说明。任何帮助或意见表示赞赏!

I'm curious as to any solutions out there for addressing object hierarchies in an ORM approach (in this instance, using Entity Framework 4). I'm working through some docs on EF4 and trying to apply it to a simple inventory tracking program. The possible types for inventory to fall into are as follows:

INVENTORY ITEM TYPES:

  • Hardware
    • PC
      • Desktop
      • Server
      • Laptop
    • Accessory
      • Input (keyboards, scanners etc)
      • Output (monitors, printers etc)
      • Storage (USB sticks, tape drives etc)
      • Communication (network cards, routers etc)
  • Software

What recommendations are there for handling enums in a situation like this? Are enums even the solution? I don't really want to have a ridiculously normalised database for such a relatively simple experiment (eg tables for InventoryType, InventorySubtype, InventoryTypeToSubtype etc). I don't really want to over-complicate my data model with each subtype being inherited even though no additional properties or methods are included (except PC types which would ideally have associated accessories and software but that's probably out of scope here).

It feels like there should be a really simple, elegant solution to this but I can't put my finger on it. Any assistance or input appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北斗星光 2024-09-02 17:15:04

我认为这需要复合设计模式: 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。

I think this calls for a composite design pattern: http://www.dofactory.com/Patterns/PatternComposite.aspx

with code like:

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

HTH.

维持三分热 2024-09-02 17:15:04

您可以使用类型层次结构...

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!");
}

虽然它会起作用,但我不确定它是否有意义。这很容易变得复杂且难以维护。

这可能更适合作为数据存储在数据库中,并编写代码以通用方式(而不是特定方式)处理数据。

每次添加新类型时,您都需要更改代码,这并不理想。

You could use a type hierarchy...

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"; } }
        }
    }
}

And then working with them might look something like this...

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

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

Though it would work, I'm not sure it makes sense. This could easily get complicated and hard to maintain.

This is probably better suited to be stored as data in a database and write your code to deal with the data in a generic manner as opposed to specific.

Every time you add a new type, you'd need to change your code, which is not ideal.

信仰 2024-09-02 17:15:04

这很难说是“可笑的标准化” - 事实上,单个自引用表足以使用邻接列表模型将信息保存在数据库中:

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; }
}

这实际上就是您所要做的一切。如果您开始拥有非常深/宽的层次结构,那么您可能需要考虑替代模型来提高性能,但鉴于此处的示例,您距离超出简单邻接列表还有很长的路要走。

忘记枚举——它们在这里没有意义。如果这是一个数据驱动的应用程序,您几乎肯定希望能够在不更改代码的情况下更改类别列表,而枚举类型需要您这样做。

This is hardly "ridiculously normalized" - in fact, a single self-referencing table is sufficient to hold the information in a database using an adjacency-list model:

Categories (CategoryID, CategoryName, ParentCategoryID)

Where ParentCategoryID references CategoryID on the same table.

This could be mapped to a very simple entity class:

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

That's really about all you have to do. If you start to have very deep/wide hierarchies then you might need to consider alternative models for performance, but given the example here, you are a long way away from outgrowing the simple adjacency list.

Forget enums - they make no sense here. If this is to be a data-driven application, you almost certainly want to be able to make changes to the category list without changing the code, which an enumeration type would require you to do.

寂寞花火° 2024-09-02 17:15:04

你的问题的要点与ORM没有太大关系,它只是一个如何为你的需求建立一个好的关系模型的问题。您已经给了自己答案:如果您不想为每个枚举建模不同的表,请不要这样做。对您的 PC 类型、配件类型等使用整数属性,并将其映射到代码中定义的枚举。这样,每当您扩展某个枚举时,您都不必更改数据库中的任何内容(甚至不需要更改任何枚举表中的数据)。

当然,在某些情况下,将枚举建模为单独的表是值得的。显然,当您必须向枚举存储附加数据(如短名称、长名称、ID 等)时,就会出现这种情况。或者当您有不同的程序时,可能使用不同的编程语言,它们都需要处理同一组枚举。或者当用户应该能够扩展 PC 类型列表而不需要新版本的程序时。

The gist of your question has not much to do with ORM, it is just a question of how to make a good relational model for your requirements. And you have given yourself the answer: if you do not want to model a different table for each of your enums, don't do it. Use an integer attribut for your type of PC, for your accessory type etc, and map it to an enum defined in your code. That way you don't have to change anything in your database (not even the data in any enum table) whenever you extend one of your enums.

There are situations, of course, where it pays for having enums modeled as separate tables. Obviously that is the case when you have to store additional data to you enums (like a short name, a long name, an ID, and so on). Or when you have different programs, perhaps in different programming languages, which all need to deal with the same set of enums. Or when a user should be able to extend the list of PC types without the need of a new version of your program.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文