2010-03-24 13 views
2

Je suis curieux de savoir s'il existe des solutions pour traiter les hiérarchies d'objets dans une approche ORM (dans ce cas, en utilisant Entity Framework 4). Je travaille sur des documents sur EF4 et essaie de l'appliquer à un simple programme de suivi d'inventaire. Les types possibles pour l'inventaire de tomber en sont les suivantes:Comment est-ce que je ferais mieux d'aborder ce type d'objet heirachy? Une sorte de hiérarchie enum?

TYPES DE POINT D'INVENTAIRE:

  • Matériel
    • PC
      • Bureau
      • serveur
      • ordinateur portable
    • Accessoire
      • entrée (claviers, scanners, etc)
      • sortie (mon contrôle de façon, imprimantes, etc.)
      • stockage (clés USB, lecteurs de bande, etc.)
      • communication (cartes réseau, les routeurs etc.)
  • Software

Quelles recommandations sont là pour traiter les énumérations dans une telle situation? Les enums sont-ils même la solution?Je ne veux pas vraiment avoir une base de données ridiculement normalisée pour une expérience relativement simple (par exemple des tables pour InventoryType, InventorySubtype, InventoryTypeToSubtype, etc.). Je ne veux pas trop compliquer mon modèle de données avec chaque sous-type hérité même si aucune propriété ou méthode supplémentaire n'est incluse (sauf les types de PC qui auraient idéalement des accessoires et des logiciels associés mais qui sont probablement hors de portée ici).

Il me semble qu'il devrait y avoir une solution vraiment simple et élégante, mais je ne peux pas mettre le doigt dessus. Toute aide ou contribution appréciée!

Répondre

1

Je pense que cela appelle un modèle de conception composite: http://www.dofactory.com/Patterns/PatternComposite.aspx

avec le code comme:

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

HTH.

+0

Je voulais quelque chose comme ça depuis le début (je ne me rendais pas compte qu'il était considéré comme un "motif de conception composite"). Je ne savais pas comment cela fonctionnerait en pratique avec les classes générées par EF. En fin de compte, le support pour les classes auto-référencées est assez simple. J'ai encore besoin de regarder un moyen efficace pour traverser l'heirachy [par exemple: Si HasAncestry (CurrentCategory, "Hardware")] mais cela devrait être assez facile. – nathanchere

+1

Perhaphs OfType <> peut vous aider dans EF - http://msdn.microsoft.com/en-us/library/bb399295.aspx – Sunny

1

Vous pouvez utiliser une hiérarchie de type ...

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

Et puis travailler avec eux pourrait ressembler à quelque chose comme ça ...

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

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

Bien qu'il travaillerait, je ne suis pas sûr Ca a du sens. Cela pourrait facilement devenir compliqué et difficile à maintenir.

Ceci est probablement mieux adapté pour être stocké sous forme de données dans une base de données et écrire votre code pour traiter les données de manière générique plutôt que spécifique.

Chaque fois que vous ajoutez un nouveau type, vous devez modifier votre code, ce qui n'est pas idéal.

1

L'essentiel de votre question n'a pas grand chose à voir avec ORM, il s'agit juste de savoir comment faire un bon modèle relationnel pour vos besoins. Et vous vous êtes donné la réponse: si vous ne voulez pas modéliser un tableau différent pour chacune de vos énumérations, ne le faites pas. Utilisez un attribut entier pour votre type de PC, pour votre type d'accessoire, etc. et mappez-le à une énumération définie dans votre code. De cette façon, vous n'avez rien à modifier dans votre base de données (pas même les données d'une table d'énumération) lorsque vous étendez l'une de vos énumérations.

Il y a bien sûr des situations où il est payant de faire modéliser des énumérations en tant que tables séparées. Évidemment, c'est le cas lorsque vous devez stocker des données supplémentaires enums (comme un nom court, un nom long, un ID, etc.). Ou lorsque vous avez différents programmes, peut-être dans des langages de programmation différents, qui doivent tous traiter avec le même ensemble d'enums. Ou quand un utilisateur devrait être en mesure d'étendre la liste des types de PC sans avoir besoin d'une nouvelle version de votre programme.

1

Ceci est à peine « ridiculement normalisée » - en fait, une seule table auto-référencement est suffisante pour contenir les informations contenues dans une base de données en utilisant un modèle liste de contiguïté:

Categories (CategoryID, CategoryName, ParentCategoryID) 

ParentCategoryID références CategoryID sur la même table.

Cela pourrait être mis en correspondance avec une classe d'entité très simple:

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

qui est vraiment tout ce que vous avez à faire. Si vous commencez à avoir des hiérarchies très profondes/larges, vous devrez peut-être envisager d'autres modèles de performance, mais étant donné l'exemple ici, vous êtes loin d'avoir dépassé la simple liste d'adjacence.Oubliez les énumérations - elles n'ont aucun sens ici. S'il s'agit d'une application pilotée par les données, vous souhaitez certainement pouvoir apporter des modifications à la liste des catégories sans modifier le code, ce que vous devez faire pour un type d'énumération.