このオブジェクトタイプHeirachyにどのように対処するのでしょうか?ある種の列挙階層?
-
22-09-2019 - |
質問
ORMアプローチでオブジェクト階層に対処するためのソリューションについては興味があります(この場合、エンティティフレームワーク4を使用)。 EF4のいくつかのドキュメントを使用して、それを簡単な在庫追跡プログラムに適用しようとしています。在庫が分類される可能性のあるタイプは次のとおりです。
在庫アイテムタイプ:
- ハードウェア
- PC
- デスクトップ
- サーバ
- ラップトップ
- アクセサリー
- 入力(キーボード、スキャナーなど)
- 出力(モニター、プリンターなど)
- ストレージ(USBスティック、テープドライブなど)
- 通信(ネットワークカード、ルーターなど)
- ソフトウェア
このような状況で列挙を処理するための推奨事項はありますか?酵素は解決策ですか?このような比較的単純な実験のために、途方もなく正規化されたデータベースを持ちたくありません(EnventoryType、InventorySubtype、InventoryTypetoSubtypeなどのテーブルなど)。追加のプロパティやメソッドが含まれていない場合でも、各サブタイプが継承されているデータモデルを過度に複雑にしたくありません(理想的には関連するアクセサリとソフトウェアがあるが、おそらくここでは範囲外です)。
これには本当にシンプルでエレガントなソリューションがあるはずだと感じていますが、指を置くことはできません。あらゆる支援や入力が高く評価されています!
解決
これには複合デザインパターンが必要だと思います。 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。
他のヒント
型階層を使用できます...
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!");
}
うまくいきますが、理にかなっているかどうかはわかりません。これは簡単に複雑になり、維持が難しくなる可能性があります。
これはおそらく、データベースにデータとして保存され、特定ではなく一般的な方法でデータを処理するためにコードを記述するのに適しています。
新しいタイプを追加するたびに、コードを変更する必要がありますが、これは理想的ではありません。
これは「途方もなく正規化された」ことはほとんどありません。実際、隣接階級モデルを使用してデータベースに情報を保持するには、単一の自己参照テーブルで十分です。
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; }
}
それは本当にあなたがしなければならないすべてについてです。非常に深い/幅の階層を持ち始めた場合は、パフォーマンスのための代替モデルを考慮する必要があるかもしれませんが、ここでの例を考えると、単純な隣接リストを上回ることから遠く離れています。
列挙を忘れてください - 彼らはここでは意味がありません。これがデータ駆動型のアプリケーションである場合、ほぼ確実に、列挙タイプが必要なコードを変更せずにカテゴリリストに変更を加えることができることを望みます。
あなたの質問の要点はORMとはあまり関係がありません。これは、要件のために良いリレーショナルモデルを作成する方法の単なる質問です。そして、あなたは自分自身に答えを与えました:あなたがあなたの列挙のそれぞれについて別のテーブルをモデル化したくないなら、それをしないでください。 PCの種類、アクセサリタイプなどに整数属性を使用し、コードで定義されている列挙にマップします。そうすれば、列挙のいずれかを拡張するたびに、データベース内の何も変更する必要はありません(列挙テーブルのデータではありません)。
もちろん、別のテーブルとしてモデル化された列挙を持っていることに支払う状況があります。明らかに、追加のデータを列挙に保存する必要がある場合です(短い名前、長い名前、IDなど)。または、おそらく異なるプログラミング言語で異なるプログラムを持っている場合、すべてが同じ列挙セットを扱う必要があります。または、ユーザーがプログラムの新しいバージョンを必要とせずにPCタイプのリストを拡張できる必要がある場合。