Как мне лучше всего обратиться к этому типу объектов heirachy? Какая-то иерархия перечислений? - PullRequest
2 голосов
/ 24 марта 2010

Мне любопытно, какие есть решения для адресации иерархий объектов в подходе ORM (в данном случае, с использованием Entity Framework 4). Я работаю над некоторыми документами по EF4 и пытаюсь применить их к простой программе отслеживания запасов. Возможны следующие типы инвентаря:

ТИПЫ ИНВЕНТАРНЫХ ПУНКТОВ:

  • Оборудование
    • PC
      • Desktop
      • Сервер
      • Ноутбук
    • Аксессуар
      • Ввод (клавиатура, сканеры и т. Д.)
      • Вывод (мониторы, принтеры и т. Д.)
      • Хранение (флешки, ленточные накопители и т. Д.)
      • Связь (сетевые карты, маршрутизаторы и т. Д.)
  • Программное обеспечение

Какие рекомендации существуют для обработки перечислений в такой ситуации? Являются ли перечисления даже решением? Я действительно не хочу иметь смехотворно нормализованную базу данных для такого относительно простого эксперимента (например, таблицы для InventoryType, InventorySubtype, InventoryTypeToSubtype и т. Д.). На самом деле я не хочу чрезмерно усложнять свою модель данных с каждым наследуемым подтипом, даже если никакие дополнительные свойства или методы не включены (за исключением типов ПК, которые в идеале имели бы связанные аксессуары и программное обеспечение, но это, вероятно, выходит за рамки этого).

Такое ощущение, что должно быть действительно простое, элегантное решение, но я не могу это понять. Любая помощь или вклад приветствуется!

Ответы [ 4 ]

1 голос
/ 24 марта 2010

Это вряд ли "смехотворно нормализовано" - на самом деле, одной таблицы с самоссылкой достаточно для хранения информации в базе данных с использованием модели списка смежности:

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

Это действительно все, что тебе нужно сделать. Если у вас начнутся очень глубокие / широкие иерархии, вам, возможно, придется рассмотреть альтернативные модели производительности, но, учитывая приведенный здесь пример, вы далеки от того, чтобы вырастить простой список смежности.

Забудьте перечисления - здесь они не имеют смысла. Если это приложение, управляемое данными, вы почти наверняка захотите внести изменения в список категорий, не изменяя код, как того требует тип перечисления.

1 голос
/ 24 марта 2010

Суть вашего вопроса не имеет ничего общего с ORM, это просто вопрос о том, как сделать хорошую реляционную модель для ваших требований. И вы дали себе ответ: если вы не хотите моделировать разные таблицы для каждого из ваших перечислений, не делайте этого. Используйте целочисленный атрибут для вашего типа ПК, типа аксессуара и т. Д. И сопоставьте его с перечислением, определенным в вашем коде. Таким образом, вам не нужно ничего менять в своей базе данных (даже данные в любой таблице перечислений), когда вы расширяете одно из перечислений.

Конечно, есть ситуации, в которых стоит перечислять перечисления в виде отдельных таблиц. Очевидно, что это тот случай, когда вам нужно хранить дополнительные данные для перечислений (например, короткое имя, длинное имя, идентификатор и т. Д.). Или когда у вас разные программы, возможно, на разных языках программирования, которые все должны иметь дело с одним и тем же набором перечислений. Или когда пользователь сможет расширить список типов ПК без необходимости новой версии вашей программы.

1 голос
/ 24 марта 2010

Я думаю, что это требует составного шаблона проектирования: 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; }
}

НТН.

1 голос
/ 24 марта 2010

Вы можете использовать иерархию типов ...

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

Хотя это будет работать, я не уверен, что это имеет смысл. Это может быть сложно и сложно поддерживать.

Это, вероятно, лучше подходит для хранения в виде данных в базе данных и написания вашего кода для обработки данных в общем виде, а не в конкретных.

Каждый раз, когда вы добавляете новый тип, вам необходимо изменить код, что не идеально.

...